struct pipe_buffer * svga_screen_buffer_wrap_surface(struct pipe_screen *screen, enum SVGA3dSurfaceFormat format, struct svga_winsys_surface *srf) { struct pipe_buffer *buf; struct svga_buffer *sbuf; struct svga_winsys_screen *sws = svga_winsys_screen(screen); buf = svga_buffer_create(screen, 0, SVGA_BUFFER_USAGE_WRAPPED, 0); if (!buf) return NULL; sbuf = svga_buffer(buf); /* * We are not the creator of this surface and therefore we must not * cache it for reuse. Set the cacheable flag to zero in the key to * prevent this. */ sbuf->key.format = format; sbuf->key.cachable = 0; sws->surface_reference(sws, &sbuf->handle, srf); return buf; }
/** * svga_fence_server_sync * * This function imports a fence from another process/device into the current * software context so that SVGA can synchronize with it. */ static void svga_fence_server_sync(struct pipe_context *pipe, struct pipe_fence_handle *fence) { struct svga_winsys_screen *sws = svga_winsys_screen(pipe->screen); struct svga_context *svga = svga_context(pipe); sws->fence_server_sync(sws, &svga->swc->imported_fence_fd, fence); }
static void vmw_dri1_present_locked(struct pipe_context *locked_pipe, struct pipe_surface *surf, const struct drm_clip_rect *rect, unsigned int num_clip, int x_draw, int y_draw, const struct drm_clip_rect *bbox, struct pipe_fence_handle **p_fence) { struct svga_winsys_surface *srf = svga_screen_texture_get_winsys_surface(surf->texture); struct vmw_svga_winsys_surface *vsrf = vmw_svga_winsys_surface(srf); struct vmw_winsys_screen *vws = vmw_winsys_screen(svga_winsys_screen(locked_pipe->screen)); struct drm_clip_rect clip; int i; struct { SVGA3dCmdHeader header; SVGA3dCmdPresent body; SVGA3dCopyRect rect; } cmd; boolean visible = FALSE; uint32_t fence_seq = 0; VMW_FUNC; cmd.header.id = SVGA_3D_CMD_PRESENT; cmd.header.size = sizeof cmd.body + sizeof cmd.rect; cmd.body.sid = vsrf->sid; for (i = 0; i < num_clip; ++i) { if (!vmw_dri1_intersect_src_bbox(&clip, x_draw, y_draw, rect++, bbox)) continue; cmd.rect.x = clip.x1; cmd.rect.y = clip.y1; cmd.rect.w = clip.x2 - clip.x1; cmd.rect.h = clip.y2 - clip.y1; cmd.rect.srcx = (int)clip.x1 - x_draw; cmd.rect.srcy = (int)clip.y1 - y_draw; vmw_printf("%s: Clip %d x %d y %d w %d h %d srcx %d srcy %d\n", __FUNCTION__, i, cmd.rect.x, cmd.rect.y, cmd.rect.w, cmd.rect.h, cmd.rect.srcx, cmd.rect.srcy); vmw_ioctl_command(vws, &cmd, sizeof cmd.header + cmd.header.size, &fence_seq); visible = TRUE; } *p_fence = (visible) ? vmw_pipe_fence(fence_seq) : NULL; vmw_svga_winsys_surface_reference(&vsrf, NULL); }
/** * svga_create_fence_fd * * Wraps a SVGA fence around an imported file descriptor. This * fd represents a fence from another process/device. The fence created * here can then be fed into fence_server_sync() so SVGA can synchronize * with an external process */ static void svga_create_fence_fd(struct pipe_context *pipe, struct pipe_fence_handle **fence, int fd, enum pipe_fd_type type) { struct svga_winsys_screen *sws = svga_winsys_screen(pipe->screen); assert(type == PIPE_FD_TYPE_NATIVE_SYNC); sws->fence_create_fd(sws, fence, fd); }
struct svga_winsys_surface * svga_screen_buffer_get_winsys_surface(struct pipe_buffer *buffer) { struct svga_winsys_screen *sws = svga_winsys_screen(buffer->screen); struct svga_winsys_surface *vsurf = NULL; assert(svga_buffer(buffer)->key.cachable == 0); svga_buffer(buffer)->key.cachable = 0; sws->surface_reference(sws, &vsurf, svga_buffer(buffer)->handle); return vsurf; }
static boolean svga_texture_get_handle(struct pipe_screen *screen, struct pipe_resource *texture, struct winsys_handle *whandle) { struct svga_winsys_screen *sws = svga_winsys_screen(texture->screen); unsigned stride; assert(svga_texture(texture)->key.cachable == 0); svga_texture(texture)->key.cachable = 0; stride = util_format_get_nblocksx(texture->format, texture->width0) * util_format_get_blocksize(texture->format); return sws->surface_get_handle(sws, svga_texture(texture)->handle, stride, whandle); }
static struct pipe_buffer * vmw_drm_buffer_from_handle(struct drm_api *drm_api, struct pipe_screen *screen, const char *name, unsigned handle) { struct vmw_svga_winsys_surface *vsrf; struct svga_winsys_surface *ssrf; struct vmw_winsys_screen *vws = vmw_winsys_screen(svga_winsys_screen(screen)); struct pipe_buffer *buf; union drm_vmw_surface_reference_arg arg; struct drm_vmw_surface_arg *req = &arg.req; struct drm_vmw_surface_create_req *rep = &arg.rep; int ret; int i; /** * The vmware device specific handle is the hardware SID. * FIXME: We probably want to move this to the ioctl implementations. */ memset(&arg, 0, sizeof(arg)); req->sid = handle; ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_REF_SURFACE, &arg, sizeof(arg)); if (ret) { fprintf(stderr, "Failed referencing shared surface. SID %d.\n" "Error %d (%s).\n", handle, ret, strerror(-ret)); return NULL; } if (rep->mip_levels[0] != 1) { fprintf(stderr, "Incorrect number of mipmap levels on shared surface." " SID %d, levels %d\n", handle, rep->mip_levels[0]); goto out_mip; } for (i=1; i < DRM_VMW_MAX_SURFACE_FACES; ++i) { if (rep->mip_levels[i] != 0) { fprintf(stderr, "Incorrect number of faces levels on shared surface." " SID %d, face %d present.\n", handle, i); goto out_mip; } } vsrf = CALLOC_STRUCT(vmw_svga_winsys_surface); if (!vsrf) goto out_mip; pipe_reference_init(&vsrf->refcnt, 1); p_atomic_set(&vsrf->validated, 0); vsrf->sid = handle; ssrf = svga_winsys_surface(vsrf); buf = svga_screen_buffer_wrap_surface(screen, rep->format, ssrf); if (!buf) vmw_svga_winsys_surface_reference(&vsrf, NULL); return buf; out_mip: vmw_ioctl_surface_destroy(vws, handle); return NULL; }