vmwgfx: Adapt to vmwgfx kernel driver 2.1

This introduces fence objects with 2.0, and present / present readback
ioctls with 2.1.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
This commit is contained in:
Thomas Hellstrom
2011-09-01 13:59:10 +02:00
parent 3c2f9cc43f
commit 5c43481aa6
6 changed files with 334 additions and 213 deletions

View File

@@ -60,6 +60,8 @@
#include "vmwgfx_saa.h"
#define XA_VERSION_MINOR_REQUIRED 0
#define DRM_VERSION_MAJOR_REQUIRED 2
#define DRM_VERSION_MINOR_REQUIRED 1
/*
* Some macros to deal with function wrapping.
@@ -268,8 +270,22 @@ drv_init_drm(ScrnInfoPtr pScrn)
ms->isMaster = TRUE;
free(BusID);
if (ms->fd >= 0)
if (ms->fd >= 0) {
drmVersionPtr ver = drmGetVersion(ms->fd);
if (ver == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Could not determine DRM version.\n");
return FALSE;
}
ms->drm_major = ver->version_major;
ms->drm_minor = ver->version_minor;
ms->drm_patch = ver->version_patchlevel;
drmFreeVersion(ver);
return TRUE;
}
return FALSE;
}
@@ -338,6 +354,22 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
if (!drv_init_drm(pScrn))
return FALSE;
if (ms->drm_major != DRM_VERSION_MAJOR_REQUIRED ||
ms->drm_minor < DRM_VERSION_MINOR_REQUIRED) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"DRM driver version is %d.%d.%d\n",
ms->drm_major, ms->drm_minor, ms->drm_patch);
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"But this driver needs %d.%d.x to work. Giving up.\n",
DRM_VERSION_MAJOR_REQUIRED,
DRM_VERSION_MINOR_REQUIRED);
return FALSE;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"DRM driver version is %d.%d.%d\n",
ms->drm_major, ms->drm_minor, ms->drm_patch);
}
ms->check_fb_size = (vmwgfx_max_fb_size(ms->fd, &ms->max_fb_size) == 0);
pScrn->monitor = pScrn->confScreen->monitor;
@@ -515,7 +547,7 @@ vmwgfx_scanout_present(ScreenPtr pScreen, int drm_fd,
return FALSE;
}
if (vmwgfx_present(drm_fd, 0, 0, dirty, handle) != 0) {
if (vmwgfx_present(drm_fd, vpix->fb_id, 0, 0, dirty, handle) != 0) {
LogMessage(X_ERROR, "Could not get present surface handle.\n");
return FALSE;
}

View File

@@ -74,6 +74,9 @@ typedef struct _modesettingRec
{
/* drm */
int fd;
int drm_major;
int drm_minor;
int drm_patch;
/* X */
EntPtr entityPrivate;
@@ -166,10 +169,6 @@ vmw_video_init_adaptor(ScrnInfoPtr pScrn);
void
vmw_video_free_adaptor(XF86VideoAdaptorPtr adaptor, Bool free_ports);
int
vmwgfx_present(int drm_fd, unsigned int dst_x, unsigned int dst_y,
RegionPtr region, uint32_t handle);
void
vmw_ctrl_ext_init(ScrnInfoPtr pScrn);

View File

@@ -31,7 +31,6 @@
#define DRM_VMW_MAX_SURFACE_FACES 6
#define DRM_VMW_MAX_MIP_LEVELS 24
#define DRM_VMW_EXT_NAME_LEN 128
#define DRM_VMW_GET_PARAM 0
#define DRM_VMW_ALLOC_DMABUF 1
@@ -48,10 +47,13 @@
#define DRM_VMW_UNREF_SURFACE 10
#define DRM_VMW_REF_SURFACE 11
#define DRM_VMW_EXECBUF 12
#define DRM_VMW_FIFO_DEBUG 13
#define DRM_VMW_GET_3D_CAP 13
#define DRM_VMW_FENCE_WAIT 14
/* guarded by minor version >= 2 */
#define DRM_VMW_UPDATE_LAYOUT 15
#define DRM_VMW_FENCE_SIGNALED 15
#define DRM_VMW_FENCE_UNREF 16
#define DRM_VMW_FENCE_EVENT 17
#define DRM_VMW_PRESENT 18
#define DRM_VMW_PRESENT_READBACK 19
/*************************************************************************/
@@ -69,10 +71,10 @@
#define DRM_VMW_PARAM_NUM_STREAMS 0
#define DRM_VMW_PARAM_NUM_FREE_STREAMS 1
#define DRM_VMW_PARAM_3D 2
#define DRM_VMW_PARAM_FIFO_OFFSET 3
#define DRM_VMW_PARAM_HW_CAPS 4
#define DRM_VMW_PARAM_FIFO_CAPS 5
#define DRM_VMW_PARAM_MAX_FB_SIZE 6
#define DRM_VMW_PARAM_HW_CAPS 3
#define DRM_VMW_PARAM_FIFO_CAPS 4
#define DRM_VMW_PARAM_MAX_FB_SIZE 5
#define DRM_VMW_PARAM_FIFO_HW_VERSION 6
/**
* struct drm_vmw_getparam_arg
@@ -89,49 +91,6 @@ struct drm_vmw_getparam_arg {
uint32_t pad64;
};
/*************************************************************************/
/**
* DRM_VMW_EXTENSION - Query device extensions.
*/
/**
* struct drm_vmw_extension_rep
*
* @exists: The queried extension exists.
* @driver_ioctl_offset: Ioctl number of the first ioctl in the extension.
* @driver_sarea_offset: Offset to any space in the DRI SAREA
* used by the extension.
* @major: Major version number of the extension.
* @minor: Minor version number of the extension.
* @pl: Patch level version number of the extension.
*
* Output argument to the DRM_VMW_EXTENSION Ioctl.
*/
struct drm_vmw_extension_rep {
int32_t exists;
uint32_t driver_ioctl_offset;
uint32_t driver_sarea_offset;
uint32_t major;
uint32_t minor;
uint32_t pl;
uint32_t pad64;
};
/**
* union drm_vmw_extension_arg
*
* @extension - Ascii name of the extension to be queried. //In
* @rep - Reply as defined above. //Out
*
* Argument to the DRM_VMW_EXTENSION Ioctl.
*/
union drm_vmw_extension_arg {
char extension[DRM_VMW_EXT_NAME_LEN];
struct drm_vmw_extension_rep rep;
};
/*************************************************************************/
/**
* DRM_VMW_CREATE_CONTEXT - Create a host context.
@@ -292,7 +251,7 @@ union drm_vmw_surface_reference_arg {
* DRM_VMW_EXECBUF
*
* Submit a command buffer for execution on the host, and return a
* fence sequence that when signaled, indicates that the command buffer has
* fence seqno that when signaled, indicates that the command buffer has
* executed.
*/
@@ -314,21 +273,30 @@ union drm_vmw_surface_reference_arg {
* Argument to the DRM_VMW_EXECBUF Ioctl.
*/
#define DRM_VMW_EXECBUF_VERSION 0
#define DRM_VMW_EXECBUF_VERSION 1
struct drm_vmw_execbuf_arg {
uint64_t commands;
uint32_t command_size;
uint32_t throttle_us;
uint64_t fence_rep;
uint32_t version;
uint32_t flags;
uint32_t version;
uint32_t flags;
};
/**
* struct drm_vmw_fence_rep
*
* @fence_seq: Fence sequence associated with a command submission.
* @handle: Fence object handle for fence associated with a command submission.
* @mask: Fence flags relevant for this fence object.
* @seqno: Fence sequence number in fifo. A fence object with a lower
* seqno will signal the EXEC flag before a fence object with a higher
* seqno. This can be used by user-space to avoid kernel calls to determine
* whether a fence has signaled the EXEC flag. Note that @seqno will
* wrap at 32-bit.
* @passed_seqno: The highest seqno number processed by the hardware
* so far. This can be used to mark user-space fence objects as signaled, and
* to determine whether a fence seqno might be stale.
* @error: This member should've been set to -EFAULT on submission.
* The following actions should be take on completion:
* error == -EFAULT: Fence communication failed. The host is synchronized.
@@ -342,9 +310,12 @@ struct drm_vmw_execbuf_arg {
*/
struct drm_vmw_fence_rep {
uint64_t fence_seq;
int32_t error;
uint32_t handle;
uint32_t mask;
uint32_t seqno;
uint32_t passed_seqno;
uint32_t pad64;
int32_t error;
};
/*************************************************************************/
@@ -433,39 +404,6 @@ struct drm_vmw_unref_dmabuf_arg {
uint32_t pad64;
};
/*************************************************************************/
/**
* DRM_VMW_FIFO_DEBUG - Get last FIFO submission.
*
* This IOCTL copies the last FIFO submission directly out of the FIFO buffer.
*/
/**
* struct drm_vmw_fifo_debug_arg
*
* @debug_buffer: User space address of a debug_buffer cast to an uint64_t //In
* @debug_buffer_size: Size in bytes of debug buffer //In
* @used_size: Number of bytes copied to the buffer // Out
* @did_not_fit: Boolean indicating that the fifo contents did not fit. //Out
*
* Argument to the DRM_VMW_FIFO_DEBUG Ioctl.
*/
struct drm_vmw_fifo_debug_arg {
uint64_t debug_buffer;
uint32_t debug_buffer_size;
uint32_t used_size;
int32_t did_not_fit;
uint32_t pad64;
};
struct drm_vmw_fence_wait_arg {
uint64_t sequence;
uint64_t kernel_cookie;
int32_t cookie_valid;
int32_t pad64;
};
/*************************************************************************/
/**
* DRM_VMW_CONTROL_STREAM - Control overlays, aka streams.
@@ -590,26 +528,197 @@ struct drm_vmw_stream_arg {
/*************************************************************************/
/**
* DRM_VMW_UPDATE_LAYOUT - Update layout
* DRM_VMW_GET_3D_CAP
*
* Read 3D capabilities from the FIFO
*
* Updates the prefered modes and connection status for connectors. The
* command conisits of one drm_vmw_update_layout_arg pointing out a array
* of num_outputs drm_vmw_rect's.
*/
/**
* struct drm_vmw_update_layout_arg
* struct drm_vmw_get_3d_cap_arg
*
* @num_outputs: number of active
* @rects: pointer to array of drm_vmw_rect
* @buffer: Pointer to a buffer for capability data, cast to an uint64_t
* @size: Max size to copy
*
* Input argument to the DRM_VMW_UPDATE_LAYOUT Ioctl.
* Input argument to the DRM_VMW_GET_3D_CAP_IOCTL
* ioctls.
*/
struct drm_vmw_update_layout_arg {
uint32_t num_outputs;
struct drm_vmw_get_3d_cap_arg {
uint64_t buffer;
uint32_t max_size;
uint32_t pad64;
uint64_t rects;
};
/*************************************************************************/
/**
* DRM_VMW_FENCE_WAIT
*
* Waits for a fence object to signal. The wait is interruptible, so that
* signals may be delivered during the interrupt. The wait may timeout,
* in which case the calls returns -EBUSY. If the wait is restarted,
* that is restarting without resetting @cookie_valid to zero,
* the timeout is computed from the first call.
*
* The flags argument to the DRM_VMW_FENCE_WAIT ioctl indicates what to wait
* on:
* DRM_VMW_FENCE_FLAG_EXEC: All commands ahead of the fence in the command
* stream
* have executed.
* DRM_VMW_FENCE_FLAG_QUERY: All query results resulting from query finish
* commands
* in the buffer given to the EXECBUF ioctl returning the fence object handle
* are available to user-space.
*
* DRM_VMW_WAIT_OPTION_UNREF: If this wait option is given, and the
* fenc wait ioctl returns 0, the fence object has been unreferenced after
* the wait.
*/
#define DRM_VMW_FENCE_FLAG_EXEC (1 << 0)
#define DRM_VMW_FENCE_FLAG_QUERY (1 << 1)
#define DRM_VMW_WAIT_OPTION_UNREF (1 << 0)
/**
* struct drm_vmw_fence_wait_arg
*
* @handle: Fence object handle as returned by the DRM_VMW_EXECBUF ioctl.
* @cookie_valid: Must be reset to 0 on first call. Left alone on restart.
* @kernel_cookie: Set to 0 on first call. Left alone on restart.
* @timeout_us: Wait timeout in microseconds. 0 for indefinite timeout.
* @lazy: Set to 1 if timing is not critical. Allow more than a kernel tick
* before returning.
* @flags: Fence flags to wait on.
* @wait_options: Options that control the behaviour of the wait ioctl.
*
* Input argument to the DRM_VMW_FENCE_WAIT ioctl.
*/
struct drm_vmw_fence_wait_arg {
uint32_t handle;
int32_t cookie_valid;
uint64_t kernel_cookie;
uint64_t timeout_us;
int32_t lazy;
int32_t flags;
int32_t wait_options;
int32_t pad64;
};
/*************************************************************************/
/**
* DRM_VMW_FENCE_SIGNALED
*
* Checks if a fence object is signaled..
*/
/**
* struct drm_vmw_fence_signaled_arg
*
* @handle: Fence object handle as returned by the DRM_VMW_EXECBUF ioctl.
* @flags: Fence object flags input to DRM_VMW_FENCE_SIGNALED ioctl
* @signaled: Out: Flags signaled.
* @sequence: Out: Highest sequence passed so far. Can be used to signal the
* EXEC flag of user-space fence objects.
*
* Input/Output argument to the DRM_VMW_FENCE_SIGNALED and DRM_VMW_FENCE_UNREF
* ioctls.
*/
struct drm_vmw_fence_signaled_arg {
uint32_t handle;
uint32_t flags;
int32_t signaled;
uint32_t passed_seqno;
uint32_t signaled_flags;
uint32_t pad64;
};
/*************************************************************************/
/**
* DRM_VMW_FENCE_UNREF
*
* Unreferences a fence object, and causes it to be destroyed if there are no
* other references to it.
*
*/
/**
* struct drm_vmw_fence_arg
*
* @handle: Fence object handle as returned by the DRM_VMW_EXECBUF ioctl.
*
* Input/Output argument to the DRM_VMW_FENCE_UNREF ioctl..
*/
struct drm_vmw_fence_arg {
uint32_t handle;
uint32_t pad64;
};
/*************************************************************************/
/**
* DRM_VMW_PRESENT
*
* Executes an SVGA present on a given fb for a given surface. The surface
* is placed on the framebuffer. Cliprects are given relative to the given
* point (the point disignated by dest_{x|y}).
*
*/
/**
* struct drm_vmw_present_arg
* @fb_id: framebuffer id to present / read back from.
* @sid: Surface id to present from.
* @dest_x: X placement coordinate for surface.
* @dest_y: Y placement coordinate for surface.
* @clips_ptr: Pointer to an array of clip rects cast to an uint64_t.
* @num_clips: Number of cliprects given relative to the framebuffer origin,
* in the same coordinate space as the frame buffer.
* @pad64: Unused 64-bit padding.
*
* Input argument to the DRM_VMW_PRESENT ioctl.
*/
struct drm_vmw_present_arg {
uint32_t fb_id;
uint32_t sid;
int32_t dest_x;
int32_t dest_y;
uint64_t clips_ptr;
uint32_t num_clips;
uint32_t pad64;
};
/*************************************************************************/
/**
* DRM_VMW_PRESENT_READBACK
*
* Executes an SVGA present readback from a given fb to the dma buffer
* currently bound as the fb. If there is no dma buffer bound to the fb,
* an error will be returned.
*
*/
/**
* struct drm_vmw_present_arg
* @fb_id: fb_id to present / read back from.
* @num_clips: Number of cliprects.
* @clips_ptr: Pointer to an array of clip rects cast to an uint64_t.
* @fence_rep: Pointer to a struct drm_vmw_fence_rep, cast to an uint64_t.
* If this member is NULL, then the ioctl should not return a fence.
*/
struct drm_vmw_present_readback_arg {
uint32_t fb_id;
uint32_t num_clips;
uint64_t clips_ptr;
uint64_t fence_rep;
};
#endif

View File

@@ -46,151 +46,138 @@
#include "vmwgfx_driver.h"
static int
vmwgfx_fence_wait(int drm_fd, uint64_t seq)
vmwgfx_fence_wait(int drm_fd, uint32_t handle, Bool unref)
{
struct drm_vmw_fence_wait_arg farg;
memset(&farg, 0, sizeof(farg));
farg.sequence = seq;
farg.handle = handle;
farg.flags = DRM_VMW_FENCE_FLAG_EXEC;
farg.timeout_us = 10*1000000;
farg.cookie_valid = 0;
if (unref)
farg.wait_options |= DRM_VMW_WAIT_OPTION_UNREF;
return drmCommandWriteRead(drm_fd, DRM_VMW_FENCE_WAIT, &farg,
sizeof(farg));
}
static void
vmwgfx_fence_unref(int drm_fd, uint32_t handle)
{
struct drm_vmw_fence_arg farg;
memset(&farg, 0, sizeof(farg));
farg.handle = handle;
(void) drmCommandWrite(drm_fd, DRM_VMW_FENCE_UNREF, &farg,
sizeof(farg));
}
int
vmwgfx_present_readback(int drm_fd, RegionPtr region)
vmwgfx_present_readback(int drm_fd, uint32_t fb_id, RegionPtr region)
{
BoxPtr clips = REGION_RECTS(region);
unsigned int num_clips = REGION_NUM_RECTS(region);
struct drm_vmw_execbuf_arg arg;
struct drm_vmw_fence_rep rep;
struct drm_vmw_present_readback_arg arg;
int ret;
unsigned int size;
unsigned i;
SVGA3dRect *cr;
struct drm_vmw_rect *rects, *r;
struct {
SVGA3dCmdHeader header;
SVGA3dRect cr;
} *cmd;
if (num_clips == 0)
return 0;
size = sizeof(*cmd) + (num_clips - 1) * sizeof(cmd->cr);
cmd = malloc(size);
if (!cmd)
rects = calloc(num_clips, sizeof(*rects));
if (!rects) {
LogMessage(X_ERROR, "Failed to alloc cliprects for "
"present readback.\n");
return -1;
cmd->header.id = SVGA_3D_CMD_PRESENT_READBACK;
cmd->header.size = num_clips * sizeof(cmd->cr);
for (i=0, cr = &cmd->cr; i < num_clips; i++, cr++, clips++) {
cr->x = (uint16_t) clips->x1;
cr->y = (uint16_t) clips->y1;
cr->w = (uint16_t) (clips->x2 - clips->x1);
cr->h = (uint16_t) (clips->y2 - clips->y1);
#if 0
LogMessage(X_INFO,
"Readback x: %u y: %u srcx: %u srcy: %u w: %u h: %u\n",
cr->x, cr->y, cr->x, cr->y, cr->w, cr->h);
#endif
}
memset(&arg, 0, sizeof(arg));
memset(&rep, 0, sizeof(rep));
arg.fb_id = fb_id;
arg.num_clips = num_clips;
arg.clips_ptr = (unsigned long) rects;
arg.fence_rep = (unsigned long) &rep;
rep.error = -EFAULT;
arg.fence_rep = (unsigned long)&rep;
arg.commands = (unsigned long)cmd;
arg.command_size = size;
arg.throttle_us = 0;
ret = drmCommandWrite(drm_fd, DRM_VMW_EXECBUF, &arg, sizeof(arg));
for (i = 0, r = rects; i < num_clips; ++i, ++r, ++clips) {
r->x = clips->x1;
r->y = clips->y1;
r->w = clips->x2 - clips->x1;
r->h = clips->y2 - clips->y1;
}
ret = drmCommandWrite(drm_fd, DRM_VMW_PRESENT_READBACK, &arg, sizeof(arg));
if (ret)
LogMessage(X_ERROR, "Present readback error %s.\n", strerror(-ret));
free(cmd);
free(rects);
/*
* Sync to avoid racing with Xorg SW rendering.
*/
if (rep.error == 0) {
ret = vmwgfx_fence_wait(drm_fd, rep.fence_seq);
if (ret)
ret = vmwgfx_fence_wait(drm_fd, rep.handle, TRUE);
if (ret) {
LogMessage(X_ERROR, "Present readback fence wait error %s.\n",
strerror(-ret));
vmwgfx_fence_unref(drm_fd, rep.handle);
}
}
return 0;
}
int
vmwgfx_present(int drm_fd, unsigned int dst_x, unsigned int dst_y,
RegionPtr region, uint32_t handle)
vmwgfx_present(int drm_fd, uint32_t fb_id, unsigned int dst_x,
unsigned int dst_y, RegionPtr region, uint32_t handle)
{
BoxPtr clips = REGION_RECTS(region);
unsigned int num_clips = REGION_NUM_RECTS(region);
struct drm_vmw_execbuf_arg arg;
struct drm_vmw_fence_rep rep;
struct drm_vmw_present_arg arg;
unsigned int i;
struct drm_vmw_rect *rects, *r;
int ret;
unsigned int size;
unsigned i;
SVGA3dCopyRect *cr;
struct {
SVGA3dCmdHeader header;
SVGA3dCmdPresent body;
SVGA3dCopyRect cr;
} *cmd;
if (num_clips == 0)
return 0;
size = sizeof(*cmd) + (num_clips - 1) * sizeof(cmd->cr);
cmd = malloc(size);
if (!cmd)
rects = calloc(num_clips, sizeof(*rects));
if (!rects) {
LogMessage(X_ERROR, "Failed to alloc cliprects for "
"present.\n");
return -1;
cmd->header.id = SVGA_3D_CMD_PRESENT;
cmd->header.size = sizeof(cmd->body) + num_clips * sizeof(cmd->cr);
cmd->body.sid = handle;
for (i=0, cr = &cmd->cr; i < num_clips; i++, cr++, clips++) {
cr->x = (uint16_t) clips->x1 + dst_x;
cr->y = (uint16_t) clips->y1 + dst_y;
cr->srcx = (uint16_t) clips->x1;
cr->srcy = (uint16_t) clips->y1;
cr->w = (uint16_t) (clips->x2 - clips->x1);
cr->h = (uint16_t) (clips->y2 - clips->y1);
#if 0
LogMessage(X_INFO, "Present: x: %u y: %u srcx: %u srcy: %u w: %u h: %u\n",
cr->x, cr->y, cr->srcx, cr->srcy, cr->w, cr->h);
#endif
}
memset(&arg, 0, sizeof(arg));
memset(&rep, 0, sizeof(rep));
arg.fb_id = fb_id;
arg.sid = handle;
arg.dest_x = dst_x;
arg.dest_y = dst_y;
arg.num_clips = num_clips;
arg.clips_ptr = (unsigned long) rects;
rep.error = -EFAULT;
arg.fence_rep = (unsigned long)&rep;
arg.commands = (unsigned long)cmd;
arg.command_size = size;
arg.throttle_us = 0;
for (i = 0, r = rects; i < num_clips; ++i, ++r, ++clips) {
r->x = clips->x1;
r->y = clips->y1;
r->w = clips->x2 - clips->x1;
r->h = clips->y2 - clips->y1;
}
ret = drmCommandWrite(drm_fd, DRM_VMW_EXECBUF, &arg, sizeof(arg));
ret = drmCommandWrite(drm_fd, DRM_VMW_PRESENT, &arg, sizeof(arg));
if (ret) {
LogMessage(X_ERROR, "Present error %s.\n", strerror(-ret));
}
free(cmd);
return 0;
free(rects);
return ((ret != 0) ? -1 : 0);
}
struct vmwgfx_int_dmabuf {
struct vmwgfx_dmabuf buf;
uint64_t map_handle;
@@ -374,10 +361,11 @@ vmwgfx_dma(unsigned int host_x, unsigned int host_y,
memset(&rep, 0, sizeof(rep));
rep.error = -EFAULT;
arg.fence_rep = (unsigned long)&rep;
arg.fence_rep = ((to_surface) ? 0UL : (unsigned long)&rep);
arg.commands = (unsigned long)cmd;
arg.command_size = size;
arg.throttle_us = 0;
arg.version = DRM_VMW_EXECBUF_VERSION;
ret = drmCommandWrite(ibuf->drm_fd, DRM_VMW_EXECBUF, &arg, sizeof(arg));
if (ret) {
@@ -386,11 +374,13 @@ vmwgfx_dma(unsigned int host_x, unsigned int host_y,
free(cmd);
if (!to_surface && rep.error == 0) {
ret = vmwgfx_fence_wait(ibuf->drm_fd, rep.fence_seq);
if (ret)
if (rep.error == 0) {
ret = vmwgfx_fence_wait(ibuf->drm_fd, rep.handle, TRUE);
if (ret) {
LogMessage(X_ERROR, "DMA from host fence wait error %s.\n",
strerror(-ret));
vmwgfx_fence_unref(ibuf->drm_fd, rep.handle);
}
}
return 0;
@@ -485,23 +475,12 @@ vmwgfx_cursor_bypass(int drm_fd, int xhot, int yhot)
int
vmwgfx_max_fb_size(int drm_fd, size_t *size)
{
drmVersionPtr ver;
int ret = -1;
uint64_t tmp_size;
ver = drmGetVersion(drm_fd);
if (ver == NULL ||
!(ver->version_major > 1 ||
(ver->version_major == 1 && ver->version_minor >= 3)))
goto out;
if (vmwgfx_get_param(drm_fd, DRM_VMW_PARAM_MAX_FB_SIZE, &tmp_size) != 0)
goto out;
return -1;
*size = tmp_size;
ret = 0;
out:
drmFreeVersion(ver);
return ret;
return 0;
}

View File

@@ -36,11 +36,11 @@
struct vmwgfx_dma_ctx;
extern int
vmwgfx_present_readback(int drm_fd, RegionPtr region);
vmwgfx_present_readback(int drm_fd, uint32_t fb_id, RegionPtr region);
extern int
vmwgfx_present(int drm_fd, unsigned int dst_x, unsigned int dst_y,
RegionPtr region, uint32_t handle);
vmwgfx_present(int drm_fd, uint32_t fb_id, unsigned int dst_x,
unsigned int dst_y, RegionPtr region, uint32_t handle);
struct vmwgfx_dmabuf {
uint32_t handle;

View File

@@ -264,7 +264,8 @@ vmwgfx_pixmap_present_readback(struct vmwgfx_saa *vsaa,
REGION_INTERSECT(vsaa->pScreen, &screen_intersection,
&screen_intersection, &intersection);
if (vmwgfx_present_readback(vsaa->drm_fd, &intersection) != 0)
if (vmwgfx_present_readback(vsaa->drm_fd, vpix->fb_id,
&intersection) != 0)
goto out_readback_err;
REGION_SUBTRACT(vsaa->pScreen, &intersection, &intersection,
@@ -926,7 +927,8 @@ vmwgfx_present_done(struct vmwgfx_saa *vsaa)
if (!vsaa->diff_valid)
return;
(void) vmwgfx_present(vsaa->drm_fd, vsaa->xdiff, vsaa->ydiff,
(void) vmwgfx_present(vsaa->drm_fd, dst_vpix->fb_id,
vsaa->xdiff, vsaa->ydiff,
&vsaa->present_region, vsaa->src_handle);
REGION_TRANSLATE(pScreen, &vsaa->present_region, vsaa->xdiff, vsaa->ydiff);