From 5c43481aa639053bbbf7fbf5f72f0edecf616731 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 1 Sep 2011 13:59:10 +0200 Subject: [PATCH] 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 Reviewed-by: Jakob Bornecrantz --- vmwgfx/vmwgfx_driver.c | 36 +++++- vmwgfx/vmwgfx_driver.h | 7 +- vmwgfx/vmwgfx_drm.h | 313 +++++++++++++++++++++++++++++++++---------------- vmwgfx/vmwgfx_drmi.c | 181 +++++++++++++--------------- vmwgfx/vmwgfx_drmi.h | 6 +- vmwgfx/vmwgfx_saa.c | 6 +- 6 files changed, 335 insertions(+), 214 deletions(-) diff --git a/vmwgfx/vmwgfx_driver.c b/vmwgfx/vmwgfx_driver.c index a682e55..42d33ab 100644 --- a/vmwgfx/vmwgfx_driver.c +++ b/vmwgfx/vmwgfx_driver.c @@ -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; } diff --git a/vmwgfx/vmwgfx_driver.h b/vmwgfx/vmwgfx_driver.h index 8b3017d..c672b62 100644 --- a/vmwgfx/vmwgfx_driver.h +++ b/vmwgfx/vmwgfx_driver.h @@ -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); diff --git a/vmwgfx/vmwgfx_drm.h b/vmwgfx/vmwgfx_drm.h index 650e6bf..bad47a7 100644 --- a/vmwgfx/vmwgfx_drm.h +++ b/vmwgfx/vmwgfx_drm.h @@ -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 @@ -91,49 +93,6 @@ struct drm_vmw_getparam_arg { /*************************************************************************/ /** - * 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. * * Allocates a device unique context id, and queues a create context command @@ -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; }; /*************************************************************************/ @@ -435,39 +406,6 @@ struct drm_vmw_unref_dmabuf_arg { /*************************************************************************/ /** - * 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. * * This IOCTL controls the overlay units of the svga device. @@ -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 diff --git a/vmwgfx/vmwgfx_drmi.c b/vmwgfx/vmwgfx_drmi.c index f6b6f0b..44904a7 100644 --- a/vmwgfx/vmwgfx_drmi.c +++ b/vmwgfx/vmwgfx_drmi.c @@ -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 { - SVGA3dCmdHeader header; - SVGA3dRect cr; - } *cmd; + struct drm_vmw_rect *rects, *r; - 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)); - - rep.error = -EFAULT; - arg.fence_rep = (unsigned long)&rep; - arg.commands = (unsigned long)cmd; - arg.command_size = size; - arg.throttle_us = 0; + 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; + + 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; } diff --git a/vmwgfx/vmwgfx_drmi.h b/vmwgfx/vmwgfx_drmi.h index 0c92719..ba4c440 100644 --- a/vmwgfx/vmwgfx_drmi.h +++ b/vmwgfx/vmwgfx_drmi.h @@ -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; diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c index 41cea13..b0c8301 100644 --- a/vmwgfx/vmwgfx_saa.c +++ b/vmwgfx/vmwgfx_saa.c @@ -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); -- 2.7.4