vmwgfx: Place overlays in GMR area if we can

When we hae screen objects we are allowed to place the overlay source
in the GMR area, do this as this will save precious VRAM.

Signed-off-by: Jakob Bornecrantz <jakob@vmware.com>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Jakob Bornecrantz 2011-10-04 20:13:25 +02:00 committed by Dave Airlie
parent 01e81419ce
commit 44031d25cc

View File

@ -97,68 +97,80 @@ static int vmw_overlay_send_put(struct vmw_private *dev_priv,
struct drm_vmw_control_stream_arg *arg, struct drm_vmw_control_stream_arg *arg,
bool interruptible) bool interruptible)
{ {
struct vmw_escape_video_flush *flush;
size_t fifo_size;
uint32_t gmrId, offset;
bool have_so = dev_priv->sou_priv ? true : false;
int i, num_items;
struct { struct {
struct vmw_escape_header escape; struct vmw_escape_header escape;
struct { struct {
struct { uint32_t cmdType;
uint32_t cmdType; uint32_t streamId;
uint32_t streamId; } header;
} header;
struct {
uint32_t registerId;
uint32_t value;
} items[SVGA_VIDEO_PITCH_3 + 1];
} body;
struct vmw_escape_video_flush flush;
} *cmds; } *cmds;
uint32_t offset; struct {
int i, ret; uint32_t registerId;
uint32_t value;
} *items;
for (;;) { /* defines are a index needs + 1 */
cmds = vmw_fifo_reserve(dev_priv, sizeof(*cmds)); if (have_so)
if (cmds) num_items = SVGA_VIDEO_DST_SCREEN_ID + 1;
break; else
num_items = SVGA_VIDEO_PITCH_3 + 1;
ret = vmw_fallback_wait(dev_priv, false, true, 0, fifo_size = sizeof(*cmds) + sizeof(*flush) + sizeof(*items) * num_items;
interruptible, 3*HZ);
if (interruptible && ret == -ERESTARTSYS) cmds = vmw_fifo_reserve(dev_priv, fifo_size);
return ret; /* hardware has hung, can't do anything here */
else if (!cmds)
BUG_ON(ret != 0); return -ENOMEM;
items = (typeof(items))&cmds[1];
flush = (struct vmw_escape_video_flush *)&items[num_items];
/* the size is header + number of items */
fill_escape(&cmds->escape, sizeof(*items) * (num_items + 1));
cmds->header.cmdType = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS;
cmds->header.streamId = arg->stream_id;
/* the IDs are neatly numbered */
for (i = 0; i < num_items; i++)
items[i].registerId = i;
vmw_dmabuf_get_id_offset(buf, &gmrId, &offset);
offset += arg->offset;
items[SVGA_VIDEO_ENABLED].value = true;
items[SVGA_VIDEO_FLAGS].value = arg->flags;
items[SVGA_VIDEO_DATA_OFFSET].value = offset;
items[SVGA_VIDEO_FORMAT].value = arg->format;
items[SVGA_VIDEO_COLORKEY].value = arg->color_key;
items[SVGA_VIDEO_SIZE].value = arg->size;
items[SVGA_VIDEO_WIDTH].value = arg->width;
items[SVGA_VIDEO_HEIGHT].value = arg->height;
items[SVGA_VIDEO_SRC_X].value = arg->src.x;
items[SVGA_VIDEO_SRC_Y].value = arg->src.y;
items[SVGA_VIDEO_SRC_WIDTH].value = arg->src.w;
items[SVGA_VIDEO_SRC_HEIGHT].value = arg->src.h;
items[SVGA_VIDEO_DST_X].value = arg->dst.x;
items[SVGA_VIDEO_DST_Y].value = arg->dst.y;
items[SVGA_VIDEO_DST_WIDTH].value = arg->dst.w;
items[SVGA_VIDEO_DST_HEIGHT].value = arg->dst.h;
items[SVGA_VIDEO_PITCH_1].value = arg->pitch[0];
items[SVGA_VIDEO_PITCH_2].value = arg->pitch[1];
items[SVGA_VIDEO_PITCH_3].value = arg->pitch[2];
if (have_so) {
items[SVGA_VIDEO_DATA_GMRID].value = gmrId;
items[SVGA_VIDEO_DST_SCREEN_ID].value = SVGA_ID_INVALID;
} }
fill_escape(&cmds->escape, sizeof(cmds->body)); fill_flush(flush, arg->stream_id);
cmds->body.header.cmdType = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS;
cmds->body.header.streamId = arg->stream_id;
for (i = 0; i <= SVGA_VIDEO_PITCH_3; i++) vmw_fifo_commit(dev_priv, fifo_size);
cmds->body.items[i].registerId = i;
offset = buf->base.offset + arg->offset;
cmds->body.items[SVGA_VIDEO_ENABLED].value = true;
cmds->body.items[SVGA_VIDEO_FLAGS].value = arg->flags;
cmds->body.items[SVGA_VIDEO_DATA_OFFSET].value = offset;
cmds->body.items[SVGA_VIDEO_FORMAT].value = arg->format;
cmds->body.items[SVGA_VIDEO_COLORKEY].value = arg->color_key;
cmds->body.items[SVGA_VIDEO_SIZE].value = arg->size;
cmds->body.items[SVGA_VIDEO_WIDTH].value = arg->width;
cmds->body.items[SVGA_VIDEO_HEIGHT].value = arg->height;
cmds->body.items[SVGA_VIDEO_SRC_X].value = arg->src.x;
cmds->body.items[SVGA_VIDEO_SRC_Y].value = arg->src.y;
cmds->body.items[SVGA_VIDEO_SRC_WIDTH].value = arg->src.w;
cmds->body.items[SVGA_VIDEO_SRC_HEIGHT].value = arg->src.h;
cmds->body.items[SVGA_VIDEO_DST_X].value = arg->dst.x;
cmds->body.items[SVGA_VIDEO_DST_Y].value = arg->dst.y;
cmds->body.items[SVGA_VIDEO_DST_WIDTH].value = arg->dst.w;
cmds->body.items[SVGA_VIDEO_DST_HEIGHT].value = arg->dst.h;
cmds->body.items[SVGA_VIDEO_PITCH_1].value = arg->pitch[0];
cmds->body.items[SVGA_VIDEO_PITCH_2].value = arg->pitch[1];
cmds->body.items[SVGA_VIDEO_PITCH_3].value = arg->pitch[2];
fill_flush(&cmds->flush, arg->stream_id);
vmw_fifo_commit(dev_priv, sizeof(*cmds));
return 0; return 0;
} }
@ -206,18 +218,22 @@ static int vmw_overlay_send_stop(struct vmw_private *dev_priv,
} }
/** /**
* Move a buffer to vram, and pin it if @pin. * Move a buffer to vram or gmr if @pin is set, else unpin the buffer.
* *
* XXX: This function is here to be changed at a later date. * With the introduction of screen objects buffers could now be
* used with GMRs instead of being locked to vram.
*/ */
static int vmw_overlay_move_buffer(struct vmw_private *dev_priv, static int vmw_overlay_move_buffer(struct vmw_private *dev_priv,
struct vmw_dma_buffer *buf, struct vmw_dma_buffer *buf,
bool pin, bool inter) bool pin, bool inter)
{ {
if (pin) if (!pin)
return vmw_dmabuf_to_vram(dev_priv, buf, true, inter);
else
return vmw_dmabuf_unpin(dev_priv, buf, inter); return vmw_dmabuf_unpin(dev_priv, buf, inter);
if (!dev_priv->sou_priv)
return vmw_dmabuf_to_vram(dev_priv, buf, true, inter);
return vmw_dmabuf_to_vram_or_gmr(dev_priv, buf, true, inter);
} }
/** /**