Commit 3eab3d9e authored by Thomas Hellstrom's avatar Thomas Hellstrom
Browse files

drm/vmwgfx: Add command buffer support v3



Add command buffer support.
Currently we don't implement preemption or fancy error handling.
Tested with a couple of mesa-demos, compiz/unity and viewperf maya-03.

v2:
- Synchronize with pending work at command buffer manager takedown.
- Add an interface to flush the current command buffer for latency-critical
  command batches and apply it to framebuffer dirtying.

v3:
- Minor fixes of definitions and typos to address reviews.
- Removed new or moved branch predictor hints.

Signed-off-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: default avatarSinclair Yeh <syeh@vmware.com>
parent cb09bbcc
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -7,6 +7,6 @@ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \
	    vmwgfx_overlay.o vmwgfx_marker.o vmwgfx_gmrid_manager.o \
	    vmwgfx_fence.o vmwgfx_dmabuf.o vmwgfx_scrn.o vmwgfx_context.o \
	    vmwgfx_surface.o vmwgfx_prime.o vmwgfx_mob.o vmwgfx_shader.o \
	    vmwgfx_cmdbuf_res.o \
	    vmwgfx_cmdbuf_res.o vmwgfx_cmdbuf.o \

obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o
+13 −0
Original line number Diff line number Diff line
@@ -72,6 +72,12 @@ static struct ttm_place mob_placement_flags = {
	.flags = VMW_PL_FLAG_MOB | TTM_PL_FLAG_CACHED
};

static struct ttm_place mob_ne_placement_flags = {
	.fpfn = 0,
	.lpfn = 0,
	.flags = VMW_PL_FLAG_MOB | TTM_PL_FLAG_CACHED | TTM_PL_FLAG_NO_EVICT
};

struct ttm_placement vmw_vram_placement = {
	.num_placement = 1,
	.placement = &vram_placement_flags,
@@ -200,6 +206,13 @@ struct ttm_placement vmw_mob_placement = {
	.busy_placement = &mob_placement_flags
};

struct ttm_placement vmw_mob_ne_placement = {
	.num_placement = 1,
	.num_busy_placement = 1,
	.placement = &mob_ne_placement_flags,
	.busy_placement = &mob_ne_placement_flags
};

struct vmw_ttm_tt {
	struct ttm_dma_tt dma_ttm;
	struct vmw_private *dev_priv;
+1315 −0

File added.

Preview size limit exceeded, changes collapsed.

+26 −0
Original line number Diff line number Diff line
@@ -278,6 +278,8 @@ static void vmw_print_capabilities(uint32_t capabilities)
		DRM_INFO("  Command Buffers 2.\n");
	if (capabilities & SVGA_CAP_GBOBJECTS)
		DRM_INFO("  Guest Backed Resources.\n");
	if (capabilities & SVGA_CAP_CMD_BUFFERS_3)
		DRM_INFO("  Command Buffers 3.\n");
}

/**
@@ -362,6 +364,17 @@ static int vmw_request_device_late(struct vmw_private *dev_priv)
		}
	}

	if (dev_priv->cman) {
		ret = vmw_cmdbuf_set_pool_size(dev_priv->cman,
					       256*4096, 2*4096);
		if (ret) {
			struct vmw_cmdbuf_man *man = dev_priv->cman;

			dev_priv->cman = NULL;
			vmw_cmdbuf_man_destroy(man);
		}
	}

	return 0;
}

@@ -375,6 +388,9 @@ static int vmw_request_device(struct vmw_private *dev_priv)
		return ret;
	}
	vmw_fence_fifo_up(dev_priv->fman);
	dev_priv->cman = vmw_cmdbuf_man_create(dev_priv);
	if (IS_ERR(dev_priv->cman))
		dev_priv->cman = NULL;

	ret = vmw_request_device_late(dev_priv);
	if (ret)
@@ -387,10 +403,14 @@ static int vmw_request_device(struct vmw_private *dev_priv)
	return 0;

out_no_query_bo:
	if (dev_priv->cman)
		vmw_cmdbuf_remove_pool(dev_priv->cman);
	if (dev_priv->has_mob) {
		(void) ttm_bo_evict_mm(&dev_priv->bdev, VMW_PL_MOB);
		vmw_otables_takedown(dev_priv);
	}
	if (dev_priv->cman)
		vmw_cmdbuf_man_destroy(dev_priv->cman);
out_no_mob:
	vmw_fence_fifo_down(dev_priv->fman);
	vmw_fifo_release(dev_priv, &dev_priv->fifo);
@@ -415,6 +435,9 @@ static void vmw_release_device_early(struct vmw_private *dev_priv)
	BUG_ON(dev_priv->pinned_bo != NULL);

	ttm_bo_unref(&dev_priv->dummy_query_bo);
	if (dev_priv->cman)
		vmw_cmdbuf_remove_pool(dev_priv->cman);

	if (dev_priv->has_mob) {
		ttm_bo_evict_mm(&dev_priv->bdev, VMW_PL_MOB);
		vmw_otables_takedown(dev_priv);
@@ -432,6 +455,9 @@ static void vmw_release_device_early(struct vmw_private *dev_priv)
static void vmw_release_device_late(struct vmw_private *dev_priv)
{
	vmw_fence_fifo_down(dev_priv->fman);
	if (dev_priv->cman)
		vmw_cmdbuf_man_destroy(dev_priv->cman);

	vmw_fifo_release(dev_priv, &dev_priv->fifo);
}

+40 −0
Original line number Diff line number Diff line
@@ -453,6 +453,8 @@ struct vmw_private {
	spinlock_t waiter_lock;
	int fence_queue_waiters; /* Protected by waiter_lock */
	int goal_queue_waiters; /* Protected by waiter_lock */
	int cmdbuf_waiters; /* Protected by irq_lock */
	int error_waiters; /* Protected by irq_lock */
	atomic_t fifo_queue_waiters;
	uint32_t last_read_seqno;
	spinlock_t irq_lock;
@@ -535,6 +537,8 @@ struct vmw_private {
	 */
	struct ttm_buffer_object *otable_bo;
	struct vmw_otable *otables;

	struct vmw_cmdbuf_man *cman;
};

static inline struct vmw_surface *vmw_res_to_srf(struct vmw_resource *res)
@@ -729,6 +733,8 @@ extern bool vmw_fifo_have_3d(struct vmw_private *dev_priv);
extern bool vmw_fifo_have_pitchlock(struct vmw_private *dev_priv);
extern int vmw_fifo_emit_dummy_query(struct vmw_private *dev_priv,
				     uint32_t cid);
extern int vmw_fifo_flush(struct vmw_private *dev_priv,
			  bool interruptible);

/**
 * TTM glue - vmwgfx_ttm_glue.c
@@ -753,6 +759,7 @@ extern struct ttm_placement vmw_sys_ne_placement;
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_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);
@@ -855,6 +862,10 @@ extern void vmw_seqno_waiter_add(struct vmw_private *dev_priv);
extern void vmw_seqno_waiter_remove(struct vmw_private *dev_priv);
extern void vmw_goal_waiter_add(struct vmw_private *dev_priv);
extern void vmw_goal_waiter_remove(struct vmw_private *dev_priv);
extern void vmw_generic_waiter_add(struct vmw_private *dev_priv, u32 flag,
				   int *waiter_count);
extern void vmw_generic_waiter_remove(struct vmw_private *dev_priv,
				      u32 flag, int *waiter_count);

/**
 * Rudimentary fence-like objects currently used only for throttling -
@@ -1077,6 +1088,35 @@ extern int vmw_cmdbuf_res_remove(struct vmw_cmdbuf_res_manager *man,
				 struct list_head *list);


/*
 * Command buffer managerment vmwgfx_cmdbuf.c
 */
struct vmw_cmdbuf_man;
struct vmw_cmdbuf_header;

extern struct vmw_cmdbuf_man *
vmw_cmdbuf_man_create(struct vmw_private *dev_priv);
extern int vmw_cmdbuf_set_pool_size(struct vmw_cmdbuf_man *man,
				    size_t size, size_t default_size);
extern void vmw_cmdbuf_remove_pool(struct vmw_cmdbuf_man *man);
extern void vmw_cmdbuf_man_destroy(struct vmw_cmdbuf_man *man);
extern int vmw_cmdbuf_idle(struct vmw_cmdbuf_man *man, bool interruptible,
			   unsigned long timeout);
extern void *vmw_cmdbuf_reserve(struct vmw_cmdbuf_man *man, size_t size,
				int ctx_id, bool interruptible,
				struct vmw_cmdbuf_header *header);
extern void vmw_cmdbuf_commit(struct vmw_cmdbuf_man *man, size_t size,
			      struct vmw_cmdbuf_header *header,
			      bool flush);
extern void vmw_cmdbuf_tasklet_schedule(struct vmw_cmdbuf_man *man);
extern void *vmw_cmdbuf_alloc(struct vmw_cmdbuf_man *man,
			      size_t size, bool interruptible,
			      struct vmw_cmdbuf_header **p_header);
extern void vmw_cmdbuf_header_free(struct vmw_cmdbuf_header *header);
extern int vmw_cmdbuf_cur_flush(struct vmw_cmdbuf_man *man,
				bool interruptible);


/**
 * Inline helper functions
 */
Loading