vmwgfx_drmi.c revision 3bfa90b6
13bfa90b6Smrg/* 23bfa90b6Smrg * Copyright 2011 VMWare, Inc. 33bfa90b6Smrg * All Rights Reserved. 43bfa90b6Smrg * 53bfa90b6Smrg * Permission is hereby granted, free of charge, to any person obtaining a 63bfa90b6Smrg * copy of this software and associated documentation files (the 73bfa90b6Smrg * "Software"), to deal in the Software without restriction, including 83bfa90b6Smrg * without limitation the rights to use, copy, modify, merge, publish, 93bfa90b6Smrg * distribute, sub license, and/or sell copies of the Software, and to 103bfa90b6Smrg * permit persons to whom the Software is furnished to do so, subject to 113bfa90b6Smrg * the following conditions: 123bfa90b6Smrg * 133bfa90b6Smrg * The above copyright notice and this permission notice (including the 143bfa90b6Smrg * next paragraph) shall be included in all copies or substantial portions 153bfa90b6Smrg * of the Software. 163bfa90b6Smrg * 173bfa90b6Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 183bfa90b6Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 193bfa90b6Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 203bfa90b6Smrg * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 213bfa90b6Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 223bfa90b6Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 233bfa90b6Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 243bfa90b6Smrg * 253bfa90b6Smrg * Author: Jakob Bornecrantz <wallbraker@gmail.com> 263bfa90b6Smrg * Author: Thomas Hellstrom <thellstrom@vmware.com> 273bfa90b6Smrg */ 283bfa90b6Smrg 293bfa90b6Smrg#ifdef HAVE_CONFIG_H 303bfa90b6Smrg#include "config.h" 313bfa90b6Smrg#endif 323bfa90b6Smrg 333bfa90b6Smrg#include <stdint.h> 343bfa90b6Smrg#include <errno.h> 353bfa90b6Smrg#include <sys/mman.h> 363bfa90b6Smrg#include "vmwgfx_drm.h" 373bfa90b6Smrg#include <xf86drm.h> 383bfa90b6Smrg#include "vmwgfx_drmi.h" 393bfa90b6Smrg 403bfa90b6Smrg#define uint32 uint32_t 413bfa90b6Smrg#define int32 int32_t 423bfa90b6Smrg#define uint16 uint16_t 433bfa90b6Smrg#define uint8 uint8_t 443bfa90b6Smrg 453bfa90b6Smrg#include "svga3d_reg.h" 463bfa90b6Smrg#include "vmwgfx_driver.h" 473bfa90b6Smrg 483bfa90b6Smrgstatic int 493bfa90b6Smrgvmwgfx_fence_wait(int drm_fd, uint32_t handle, Bool unref) 503bfa90b6Smrg{ 513bfa90b6Smrg struct drm_vmw_fence_wait_arg farg; 523bfa90b6Smrg memset(&farg, 0, sizeof(farg)); 533bfa90b6Smrg 543bfa90b6Smrg farg.handle = handle; 553bfa90b6Smrg farg.flags = DRM_VMW_FENCE_FLAG_EXEC; 563bfa90b6Smrg farg.timeout_us = 10*1000000; 573bfa90b6Smrg farg.cookie_valid = 0; 583bfa90b6Smrg 593bfa90b6Smrg if (unref) 603bfa90b6Smrg farg.wait_options |= DRM_VMW_WAIT_OPTION_UNREF; 613bfa90b6Smrg 623bfa90b6Smrg return drmCommandWriteRead(drm_fd, DRM_VMW_FENCE_WAIT, &farg, 633bfa90b6Smrg sizeof(farg)); 643bfa90b6Smrg} 653bfa90b6Smrg 663bfa90b6Smrgstatic void 673bfa90b6Smrgvmwgfx_fence_unref(int drm_fd, uint32_t handle) 683bfa90b6Smrg{ 693bfa90b6Smrg struct drm_vmw_fence_arg farg; 703bfa90b6Smrg memset(&farg, 0, sizeof(farg)); 713bfa90b6Smrg 723bfa90b6Smrg farg.handle = handle; 733bfa90b6Smrg 743bfa90b6Smrg (void) drmCommandWrite(drm_fd, DRM_VMW_FENCE_UNREF, &farg, 753bfa90b6Smrg sizeof(farg)); 763bfa90b6Smrg} 773bfa90b6Smrg 783bfa90b6Smrg 793bfa90b6Smrgint 803bfa90b6Smrgvmwgfx_present_readback(int drm_fd, uint32_t fb_id, RegionPtr region) 813bfa90b6Smrg{ 823bfa90b6Smrg BoxPtr clips = REGION_RECTS(region); 833bfa90b6Smrg unsigned int num_clips = REGION_NUM_RECTS(region); 843bfa90b6Smrg struct drm_vmw_fence_rep rep; 853bfa90b6Smrg struct drm_vmw_present_readback_arg arg; 863bfa90b6Smrg int ret; 873bfa90b6Smrg unsigned i; 883bfa90b6Smrg struct drm_vmw_rect *rects, *r; 893bfa90b6Smrg 903bfa90b6Smrg rects = calloc(num_clips, sizeof(*rects)); 913bfa90b6Smrg if (!rects) { 923bfa90b6Smrg LogMessage(X_ERROR, "Failed to alloc cliprects for " 933bfa90b6Smrg "present readback.\n"); 943bfa90b6Smrg return -1; 953bfa90b6Smrg } 963bfa90b6Smrg 973bfa90b6Smrg memset(&arg, 0, sizeof(arg)); 983bfa90b6Smrg memset(&rep, 0, sizeof(rep)); 993bfa90b6Smrg 1003bfa90b6Smrg arg.fb_id = fb_id; 1013bfa90b6Smrg arg.num_clips = num_clips; 1023bfa90b6Smrg arg.clips_ptr = (unsigned long) rects; 1033bfa90b6Smrg arg.fence_rep = (unsigned long) &rep; 1043bfa90b6Smrg rep.error = -EFAULT; 1053bfa90b6Smrg 1063bfa90b6Smrg for (i = 0, r = rects; i < num_clips; ++i, ++r, ++clips) { 1073bfa90b6Smrg r->x = clips->x1; 1083bfa90b6Smrg r->y = clips->y1; 1093bfa90b6Smrg r->w = clips->x2 - clips->x1; 1103bfa90b6Smrg r->h = clips->y2 - clips->y1; 1113bfa90b6Smrg } 1123bfa90b6Smrg 1133bfa90b6Smrg ret = drmCommandWrite(drm_fd, DRM_VMW_PRESENT_READBACK, &arg, sizeof(arg)); 1143bfa90b6Smrg if (ret) 1153bfa90b6Smrg LogMessage(X_ERROR, "Present readback error %s.\n", strerror(-ret)); 1163bfa90b6Smrg free(rects); 1173bfa90b6Smrg 1183bfa90b6Smrg /* 1193bfa90b6Smrg * Sync to avoid racing with Xorg SW rendering. 1203bfa90b6Smrg */ 1213bfa90b6Smrg 1223bfa90b6Smrg if (rep.error == 0) { 1233bfa90b6Smrg ret = vmwgfx_fence_wait(drm_fd, rep.handle, TRUE); 1243bfa90b6Smrg if (ret) { 1253bfa90b6Smrg LogMessage(X_ERROR, "Present readback fence wait error %s.\n", 1263bfa90b6Smrg strerror(-ret)); 1273bfa90b6Smrg vmwgfx_fence_unref(drm_fd, rep.handle); 1283bfa90b6Smrg } 1293bfa90b6Smrg } 1303bfa90b6Smrg 1313bfa90b6Smrg return 0; 1323bfa90b6Smrg} 1333bfa90b6Smrg 1343bfa90b6Smrg 1353bfa90b6Smrgint 1363bfa90b6Smrgvmwgfx_present(int drm_fd, uint32_t fb_id, unsigned int dst_x, 1373bfa90b6Smrg unsigned int dst_y, RegionPtr region, uint32_t handle) 1383bfa90b6Smrg{ 1393bfa90b6Smrg BoxPtr clips = REGION_RECTS(region); 1403bfa90b6Smrg unsigned int num_clips = REGION_NUM_RECTS(region); 1413bfa90b6Smrg struct drm_vmw_present_arg arg; 1423bfa90b6Smrg unsigned int i; 1433bfa90b6Smrg struct drm_vmw_rect *rects, *r; 1443bfa90b6Smrg int ret; 1453bfa90b6Smrg 1463bfa90b6Smrg if (num_clips == 0) 1473bfa90b6Smrg return 0; 1483bfa90b6Smrg 1493bfa90b6Smrg rects = calloc(num_clips, sizeof(*rects)); 1503bfa90b6Smrg if (!rects) { 1513bfa90b6Smrg LogMessage(X_ERROR, "Failed to alloc cliprects for " 1523bfa90b6Smrg "present.\n"); 1533bfa90b6Smrg return -1; 1543bfa90b6Smrg } 1553bfa90b6Smrg 1563bfa90b6Smrg memset(&arg, 0, sizeof(arg)); 1573bfa90b6Smrg arg.fb_id = fb_id; 1583bfa90b6Smrg arg.sid = handle; 1593bfa90b6Smrg arg.dest_x = dst_x; 1603bfa90b6Smrg arg.dest_y = dst_y; 1613bfa90b6Smrg arg.num_clips = num_clips; 1623bfa90b6Smrg arg.clips_ptr = (unsigned long) rects; 1633bfa90b6Smrg 1643bfa90b6Smrg for (i = 0, r = rects; i < num_clips; ++i, ++r, ++clips) { 1653bfa90b6Smrg r->x = clips->x1; 1663bfa90b6Smrg r->y = clips->y1; 1673bfa90b6Smrg r->w = clips->x2 - clips->x1; 1683bfa90b6Smrg r->h = clips->y2 - clips->y1; 1693bfa90b6Smrg } 1703bfa90b6Smrg 1713bfa90b6Smrg ret = drmCommandWrite(drm_fd, DRM_VMW_PRESENT, &arg, sizeof(arg)); 1723bfa90b6Smrg if (ret) { 1733bfa90b6Smrg LogMessage(X_ERROR, "Present error %s.\n", strerror(-ret)); 1743bfa90b6Smrg } 1753bfa90b6Smrg 1763bfa90b6Smrg free(rects); 1773bfa90b6Smrg return ((ret != 0) ? -1 : 0); 1783bfa90b6Smrg} 1793bfa90b6Smrg 1803bfa90b6Smrg 1813bfa90b6Smrgstruct vmwgfx_int_dmabuf { 1823bfa90b6Smrg struct vmwgfx_dmabuf buf; 1833bfa90b6Smrg uint64_t map_handle; 1843bfa90b6Smrg uint64_t sync_handle; 1853bfa90b6Smrg int sync_valid; 1863bfa90b6Smrg int drm_fd; 1873bfa90b6Smrg uint32_t map_count; 1883bfa90b6Smrg void *addr; 1893bfa90b6Smrg}; 1903bfa90b6Smrg 1913bfa90b6Smrgstatic inline struct vmwgfx_int_dmabuf * 1923bfa90b6Smrgvmwgfx_int_dmabuf(struct vmwgfx_dmabuf *buf) 1933bfa90b6Smrg{ 1943bfa90b6Smrg return (struct vmwgfx_int_dmabuf *) buf; 1953bfa90b6Smrg} 1963bfa90b6Smrg 1973bfa90b6Smrgstruct vmwgfx_dmabuf* 1983bfa90b6Smrgvmwgfx_dmabuf_alloc(int drm_fd, size_t size) 1993bfa90b6Smrg{ 2003bfa90b6Smrg union drm_vmw_alloc_dmabuf_arg arg; 2013bfa90b6Smrg struct vmwgfx_dmabuf *buf; 2023bfa90b6Smrg struct vmwgfx_int_dmabuf *ibuf; 2033bfa90b6Smrg int ret; 2043bfa90b6Smrg 2053bfa90b6Smrg ibuf = calloc(1, sizeof(*ibuf)); 2063bfa90b6Smrg if (!ibuf) 2073bfa90b6Smrg return NULL; 2083bfa90b6Smrg 2093bfa90b6Smrg buf = &ibuf->buf; 2103bfa90b6Smrg memset(&arg, 0, sizeof(arg)); 2113bfa90b6Smrg arg.req.size = size; 2123bfa90b6Smrg 2133bfa90b6Smrg ret = drmCommandWriteRead(drm_fd, DRM_VMW_ALLOC_DMABUF, &arg, 2143bfa90b6Smrg sizeof(arg)); 2153bfa90b6Smrg if (ret) 2163bfa90b6Smrg goto out_kernel_fail; 2173bfa90b6Smrg 2183bfa90b6Smrg ibuf = vmwgfx_int_dmabuf(buf); 2193bfa90b6Smrg ibuf->map_handle = arg.rep.map_handle; 2203bfa90b6Smrg ibuf->drm_fd = drm_fd; 2213bfa90b6Smrg buf->handle = arg.rep.handle; 2223bfa90b6Smrg buf->gmr_id = arg.rep.cur_gmr_id; 2233bfa90b6Smrg buf->gmr_offset = arg.rep.cur_gmr_offset; 2243bfa90b6Smrg buf->size = size; 2253bfa90b6Smrg 2263bfa90b6Smrg return buf; 2273bfa90b6Smrg out_kernel_fail: 2283bfa90b6Smrg free(buf); 2293bfa90b6Smrg return NULL; 2303bfa90b6Smrg} 2313bfa90b6Smrg 2323bfa90b6Smrgvoid * 2333bfa90b6Smrgvmwgfx_dmabuf_map(struct vmwgfx_dmabuf *buf) 2343bfa90b6Smrg{ 2353bfa90b6Smrg struct vmwgfx_int_dmabuf *ibuf = vmwgfx_int_dmabuf(buf); 2363bfa90b6Smrg 2373bfa90b6Smrg if (ibuf->addr) 2383bfa90b6Smrg return ibuf->addr; 2393bfa90b6Smrg 2403bfa90b6Smrg ibuf->addr = mmap(NULL, buf->size, PROT_READ | PROT_WRITE, MAP_SHARED, 2413bfa90b6Smrg ibuf->drm_fd, ibuf->map_handle); 2423bfa90b6Smrg 2433bfa90b6Smrg if (ibuf->addr == MAP_FAILED) { 2443bfa90b6Smrg ibuf->addr = NULL; 2453bfa90b6Smrg return NULL; 2463bfa90b6Smrg } 2473bfa90b6Smrg 2483bfa90b6Smrg ibuf->map_count++; 2493bfa90b6Smrg return ibuf->addr; 2503bfa90b6Smrg} 2513bfa90b6Smrg 2523bfa90b6Smrgvoid 2533bfa90b6Smrgvmwgfx_dmabuf_unmap(struct vmwgfx_dmabuf *buf) 2543bfa90b6Smrg{ 2553bfa90b6Smrg struct vmwgfx_int_dmabuf *ibuf = vmwgfx_int_dmabuf(buf); 2563bfa90b6Smrg 2573bfa90b6Smrg if (--ibuf->map_count) 2583bfa90b6Smrg return; 2593bfa90b6Smrg 2603bfa90b6Smrg /* 2613bfa90b6Smrg * It's a pretty important performance optimzation not to call 2623bfa90b6Smrg * munmap here, although we should watch out for cases where we might fill 2633bfa90b6Smrg * the virtual memory space of the process. 2643bfa90b6Smrg */ 2653bfa90b6Smrg} 2663bfa90b6Smrg 2673bfa90b6Smrgvoid 2683bfa90b6Smrgvmwgfx_dmabuf_destroy(struct vmwgfx_dmabuf *buf) 2693bfa90b6Smrg{ 2703bfa90b6Smrg struct vmwgfx_int_dmabuf *ibuf = vmwgfx_int_dmabuf(buf); 2713bfa90b6Smrg struct drm_vmw_unref_dmabuf_arg arg; 2723bfa90b6Smrg 2733bfa90b6Smrg if (ibuf->addr) { 2743bfa90b6Smrg munmap(ibuf->addr, buf->size); 2753bfa90b6Smrg ibuf->addr = NULL; 2763bfa90b6Smrg } 2773bfa90b6Smrg 2783bfa90b6Smrg memset(&arg, 0, sizeof(arg)); 2793bfa90b6Smrg arg.handle = buf->handle; 2803bfa90b6Smrg 2813bfa90b6Smrg (void) drmCommandWrite(ibuf->drm_fd, DRM_VMW_UNREF_DMABUF, &arg, 2823bfa90b6Smrg sizeof(arg)); 2833bfa90b6Smrg free(buf); 2843bfa90b6Smrg} 2853bfa90b6Smrg 2863bfa90b6Smrgint 2873bfa90b6Smrgvmwgfx_dma(unsigned int host_x, unsigned int host_y, 2883bfa90b6Smrg RegionPtr region, struct vmwgfx_dmabuf *buf, 2893bfa90b6Smrg uint32_t buf_pitch, uint32_t surface_handle, int to_surface) 2903bfa90b6Smrg{ 2913bfa90b6Smrg BoxPtr clips = REGION_RECTS(region); 2923bfa90b6Smrg unsigned int num_clips = REGION_NUM_RECTS(region); 2933bfa90b6Smrg struct drm_vmw_execbuf_arg arg; 2943bfa90b6Smrg struct drm_vmw_fence_rep rep; 2953bfa90b6Smrg int ret; 2963bfa90b6Smrg unsigned int size; 2973bfa90b6Smrg unsigned i; 2983bfa90b6Smrg SVGA3dCopyBox *cb; 2993bfa90b6Smrg SVGA3dCmdSurfaceDMASuffix *suffix; 3003bfa90b6Smrg SVGA3dCmdSurfaceDMA *body; 3013bfa90b6Smrg struct vmwgfx_int_dmabuf *ibuf = vmwgfx_int_dmabuf(buf); 3023bfa90b6Smrg 3033bfa90b6Smrg struct { 3043bfa90b6Smrg SVGA3dCmdHeader header; 3053bfa90b6Smrg SVGA3dCmdSurfaceDMA body; 3063bfa90b6Smrg SVGA3dCopyBox cb; 3073bfa90b6Smrg } *cmd; 3083bfa90b6Smrg 3093bfa90b6Smrg if (num_clips == 0) 3103bfa90b6Smrg return 0; 3113bfa90b6Smrg 3123bfa90b6Smrg size = sizeof(*cmd) + (num_clips - 1) * sizeof(cmd->cb) + 3133bfa90b6Smrg sizeof(*suffix); 3143bfa90b6Smrg cmd = malloc(size); 3153bfa90b6Smrg if (!cmd) 3163bfa90b6Smrg return -1; 3173bfa90b6Smrg 3183bfa90b6Smrg cmd->header.id = SVGA_3D_CMD_SURFACE_DMA; 3193bfa90b6Smrg cmd->header.size = sizeof(cmd->body) + num_clips * sizeof(cmd->cb) + 3203bfa90b6Smrg sizeof(*suffix); 3213bfa90b6Smrg cb = &cmd->cb; 3223bfa90b6Smrg 3233bfa90b6Smrg suffix = (SVGA3dCmdSurfaceDMASuffix *) &cb[num_clips]; 3243bfa90b6Smrg suffix->suffixSize = sizeof(*suffix); 3253bfa90b6Smrg suffix->maximumOffset = (uint32_t) -1; 3263bfa90b6Smrg suffix->flags.discard = 0; 3273bfa90b6Smrg suffix->flags.unsynchronized = 0; 3283bfa90b6Smrg suffix->flags.reserved = 0; 3293bfa90b6Smrg 3303bfa90b6Smrg body = &cmd->body; 3313bfa90b6Smrg body->guest.ptr.gmrId = buf->gmr_id; 3323bfa90b6Smrg body->guest.ptr.offset = buf->gmr_offset; 3333bfa90b6Smrg body->guest.pitch = buf_pitch; 3343bfa90b6Smrg body->host.sid = surface_handle; 3353bfa90b6Smrg body->host.face = 0; 3363bfa90b6Smrg body->host.mipmap = 0; 3373bfa90b6Smrg 3383bfa90b6Smrg body->transfer = (to_surface ? SVGA3D_WRITE_HOST_VRAM : 3393bfa90b6Smrg SVGA3D_READ_HOST_VRAM); 3403bfa90b6Smrg 3413bfa90b6Smrg 3423bfa90b6Smrg for (i=0; i < num_clips; i++, cb++, clips++) { 3433bfa90b6Smrg cb->x = (uint16_t) clips->x1 + host_x; 3443bfa90b6Smrg cb->y = (uint16_t) clips->y1 + host_y; 3453bfa90b6Smrg cb->z = 0; 3463bfa90b6Smrg cb->srcx = (uint16_t) clips->x1; 3473bfa90b6Smrg cb->srcy = (uint16_t) clips->y1; 3483bfa90b6Smrg cb->srcz = 0; 3493bfa90b6Smrg cb->w = (uint16_t) (clips->x2 - clips->x1); 3503bfa90b6Smrg cb->h = (uint16_t) (clips->y2 - clips->y1); 3513bfa90b6Smrg cb->d = 1; 3523bfa90b6Smrg#if 0 3533bfa90b6Smrg LogMessage(X_INFO, "DMA! x: %u y: %u srcx: %u srcy: %u w: %u h: %u %s\n", 3543bfa90b6Smrg cb->x, cb->y, cb->srcx, cb->srcy, cb->w, cb->h, 3553bfa90b6Smrg to_surface ? "to" : "from"); 3563bfa90b6Smrg#endif 3573bfa90b6Smrg 3583bfa90b6Smrg } 3593bfa90b6Smrg 3603bfa90b6Smrg memset(&arg, 0, sizeof(arg)); 3613bfa90b6Smrg memset(&rep, 0, sizeof(rep)); 3623bfa90b6Smrg 3633bfa90b6Smrg rep.error = -EFAULT; 3643bfa90b6Smrg arg.fence_rep = ((to_surface) ? 0UL : (unsigned long)&rep); 3653bfa90b6Smrg arg.commands = (unsigned long)cmd; 3663bfa90b6Smrg arg.command_size = size; 3673bfa90b6Smrg arg.throttle_us = 0; 3683bfa90b6Smrg arg.version = DRM_VMW_EXECBUF_VERSION; 3693bfa90b6Smrg 3703bfa90b6Smrg ret = drmCommandWrite(ibuf->drm_fd, DRM_VMW_EXECBUF, &arg, sizeof(arg)); 3713bfa90b6Smrg if (ret) { 3723bfa90b6Smrg LogMessage(X_ERROR, "DMA error %s.\n", strerror(-ret)); 3733bfa90b6Smrg } 3743bfa90b6Smrg 3753bfa90b6Smrg free(cmd); 3763bfa90b6Smrg 3773bfa90b6Smrg if (rep.error == 0) { 3783bfa90b6Smrg ret = vmwgfx_fence_wait(ibuf->drm_fd, rep.handle, TRUE); 3793bfa90b6Smrg if (ret) { 3803bfa90b6Smrg LogMessage(X_ERROR, "DMA from host fence wait error %s.\n", 3813bfa90b6Smrg strerror(-ret)); 3823bfa90b6Smrg vmwgfx_fence_unref(ibuf->drm_fd, rep.handle); 3833bfa90b6Smrg } 3843bfa90b6Smrg } 3853bfa90b6Smrg 3863bfa90b6Smrg return 0; 3873bfa90b6Smrg} 3883bfa90b6Smrg 3893bfa90b6Smrgint 3903bfa90b6Smrgvmwgfx_get_param(int drm_fd, uint32_t param, uint64_t *out) 3913bfa90b6Smrg{ 3923bfa90b6Smrg struct drm_vmw_getparam_arg gp_arg; 3933bfa90b6Smrg int ret; 3943bfa90b6Smrg 3953bfa90b6Smrg memset(&gp_arg, 0, sizeof(gp_arg)); 3963bfa90b6Smrg gp_arg.param = param; 3973bfa90b6Smrg ret = drmCommandWriteRead(drm_fd, DRM_VMW_GET_PARAM, 3983bfa90b6Smrg &gp_arg, sizeof(gp_arg)); 3993bfa90b6Smrg 4003bfa90b6Smrg if (ret == 0) { 4013bfa90b6Smrg *out = gp_arg.value; 4023bfa90b6Smrg } 4033bfa90b6Smrg 4043bfa90b6Smrg return ret; 4053bfa90b6Smrg} 4063bfa90b6Smrg 4073bfa90b6Smrgint 4083bfa90b6Smrgvmwgfx_num_streams(int drm_fd, uint32_t *ntot, uint32_t *nfree) 4093bfa90b6Smrg{ 4103bfa90b6Smrg uint64_t v1, v2; 4113bfa90b6Smrg int ret; 4123bfa90b6Smrg 4133bfa90b6Smrg ret = vmwgfx_get_param(drm_fd, DRM_VMW_PARAM_NUM_STREAMS, &v1); 4143bfa90b6Smrg if (ret) 4153bfa90b6Smrg return ret; 4163bfa90b6Smrg 4173bfa90b6Smrg ret = vmwgfx_get_param(drm_fd, DRM_VMW_PARAM_NUM_FREE_STREAMS, &v2); 4183bfa90b6Smrg if (ret) 4193bfa90b6Smrg return ret; 4203bfa90b6Smrg 4213bfa90b6Smrg *ntot = (uint32_t)v1; 4223bfa90b6Smrg *nfree = (uint32_t)v2; 4233bfa90b6Smrg 4243bfa90b6Smrg return 0; 4253bfa90b6Smrg} 4263bfa90b6Smrg 4273bfa90b6Smrgint 4283bfa90b6Smrgvmwgfx_claim_stream(int drm_fd, uint32_t *out) 4293bfa90b6Smrg{ 4303bfa90b6Smrg struct drm_vmw_stream_arg s_arg; 4313bfa90b6Smrg int ret; 4323bfa90b6Smrg 4333bfa90b6Smrg ret = drmCommandRead(drm_fd, DRM_VMW_CLAIM_STREAM, 4343bfa90b6Smrg &s_arg, sizeof(s_arg)); 4353bfa90b6Smrg 4363bfa90b6Smrg if (ret) 4373bfa90b6Smrg return -1; 4383bfa90b6Smrg 4393bfa90b6Smrg *out = s_arg.stream_id; 4403bfa90b6Smrg return 0; 4413bfa90b6Smrg} 4423bfa90b6Smrg 4433bfa90b6Smrgint 4443bfa90b6Smrgvmwgfx_unref_stream(int drm_fd, uint32_t stream_id) 4453bfa90b6Smrg{ 4463bfa90b6Smrg struct drm_vmw_stream_arg s_arg; 4473bfa90b6Smrg int ret; 4483bfa90b6Smrg 4493bfa90b6Smrg memset(&s_arg, 0, sizeof(s_arg)); 4503bfa90b6Smrg s_arg.stream_id = stream_id; 4513bfa90b6Smrg 4523bfa90b6Smrg ret = drmCommandWrite(drm_fd, DRM_VMW_UNREF_STREAM, 4533bfa90b6Smrg &s_arg, sizeof(s_arg)); 4543bfa90b6Smrg 4553bfa90b6Smrg return (ret != 0) ? -1 : 0; 4563bfa90b6Smrg} 4573bfa90b6Smrg 4583bfa90b6Smrgint 4593bfa90b6Smrgvmwgfx_cursor_bypass(int drm_fd, int xhot, int yhot) 4603bfa90b6Smrg{ 4613bfa90b6Smrg struct drm_vmw_cursor_bypass_arg arg; 4623bfa90b6Smrg int ret; 4633bfa90b6Smrg 4643bfa90b6Smrg memset(&arg, 0, sizeof(arg)); 4653bfa90b6Smrg arg.flags = DRM_VMW_CURSOR_BYPASS_ALL; 4663bfa90b6Smrg arg.xhot = xhot; 4673bfa90b6Smrg arg.yhot = yhot; 4683bfa90b6Smrg 4693bfa90b6Smrg ret = drmCommandWrite(drm_fd, DRM_VMW_CURSOR_BYPASS, 4703bfa90b6Smrg &arg, sizeof(arg)); 4713bfa90b6Smrg 4723bfa90b6Smrg return ret; 4733bfa90b6Smrg} 4743bfa90b6Smrg 4753bfa90b6Smrgint 4763bfa90b6Smrgvmwgfx_update_gui_layout(int drm_fd, unsigned int num_rects, 4773bfa90b6Smrg struct drm_vmw_rect *rects) 4783bfa90b6Smrg{ 4793bfa90b6Smrg struct drm_vmw_update_layout_arg arg; 4803bfa90b6Smrg 4813bfa90b6Smrg memset(&arg, 0, sizeof(arg)); 4823bfa90b6Smrg 4833bfa90b6Smrg arg.num_outputs = num_rects; 4843bfa90b6Smrg arg.rects = (unsigned long) rects; 4853bfa90b6Smrg 4863bfa90b6Smrg return drmCommandWrite(drm_fd, DRM_VMW_UPDATE_LAYOUT, &arg, 4873bfa90b6Smrg sizeof(arg)); 4883bfa90b6Smrg} 4893bfa90b6Smrg 4903bfa90b6Smrg 4913bfa90b6Smrgint 4923bfa90b6Smrgvmwgfx_max_fb_size(int drm_fd, size_t *size) 4933bfa90b6Smrg{ 4943bfa90b6Smrg uint64_t tmp_size; 4953bfa90b6Smrg 4963bfa90b6Smrg if (vmwgfx_get_param(drm_fd, DRM_VMW_PARAM_MAX_FB_SIZE, &tmp_size) != 0) 4973bfa90b6Smrg return -1; 4983bfa90b6Smrg 4993bfa90b6Smrg *size = tmp_size; 5003bfa90b6Smrg 5013bfa90b6Smrg return 0; 5023bfa90b6Smrg} 503