Beispiel #1
0
static void
vmw_svga_winsys_surface_ref(struct svga_winsys_screen *sws,
			    struct svga_winsys_surface **pDst,
			    struct svga_winsys_surface *src)
{
   struct vmw_svga_winsys_surface *d_vsurf = vmw_svga_winsys_surface(*pDst);
   struct vmw_svga_winsys_surface *s_vsurf = vmw_svga_winsys_surface(src);

   vmw_svga_winsys_surface_reference(&d_vsurf, s_vsurf);
   *pDst = svga_winsys_surface(d_vsurf);
}
Beispiel #2
0
static void
vmw_swc_surface_relocation(struct svga_winsys_context *swc,
                           uint32 *where,
                           uint32 *mobid,
                           struct svga_winsys_surface *surface,
                           unsigned flags)
{
   struct vmw_svga_winsys_surface *vsurf;

   assert(swc->have_gb_objects || mobid == NULL);

   if(!surface) {
      *where = SVGA3D_INVALID_ID;
      if (mobid)
         *mobid = SVGA3D_INVALID_ID;
      return;
   }

   vsurf = vmw_svga_winsys_surface(surface);
   vmw_swc_surface_only_relocation(swc, where, vsurf, flags);

   if (swc->have_gb_objects && vsurf->buf != NULL) {

      /*
       * Make sure backup buffer ends up fenced.
       */

      pipe_mutex_lock(vsurf->mutex);
      assert(vsurf->buf != NULL);
      
      vmw_swc_mob_relocation(swc, mobid, NULL, (struct svga_winsys_buffer *)
                             vsurf->buf, 0, flags);
      pipe_mutex_unlock(vsurf->mutex);
   }
}
Beispiel #3
0
static boolean
vmw_svga_winsys_surface_is_flushed(struct svga_winsys_screen *sws,
                                   struct svga_winsys_surface *surface)
{
   struct vmw_svga_winsys_surface *vsurf = vmw_svga_winsys_surface(surface);
   return (p_atomic_read(&vsurf->validated) == 0);
}
Beispiel #4
0
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);
}
Beispiel #5
0
void
vmw_svga_winsys_surface_unmap(struct svga_winsys_context *swc,
                              struct svga_winsys_surface *srf,
                              boolean *rebind)
{
    struct vmw_svga_winsys_surface *vsrf = vmw_svga_winsys_surface(srf);
    pipe_mutex_lock(vsrf->mutex);
    if (--vsrf->mapcount == 0) {
        *rebind = vsrf->rebind;
        vsrf->rebind = FALSE;
        vmw_svga_winsys_buffer_unmap(&vsrf->screen->base, vsrf->buf);
    }
    pipe_mutex_unlock(vsrf->mutex);
}
Beispiel #6
0
static boolean
vmw_drm_handle_from_buffer(struct drm_api *drm_api,
                           struct pipe_screen *screen,
			   struct pipe_buffer *buffer,
			   unsigned *handle)
{
    struct svga_winsys_surface *surface =
	svga_screen_buffer_get_winsys_surface(buffer);
    struct vmw_svga_winsys_surface *vsrf;

    if (!surface)
	return FALSE;

    vsrf = vmw_svga_winsys_surface(surface);
    *handle = vsrf->sid;
    vmw_svga_winsys_surface_reference(&vsrf, NULL);
    return TRUE;
}
Beispiel #7
0
static boolean
vmw_drm_surface_get_handle(struct svga_winsys_screen *sws,
			   struct svga_winsys_surface *surface,
			   unsigned stride,
			   struct winsys_handle *whandle)
{
    struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
    struct vmw_svga_winsys_surface *vsrf;
    int ret;

    if (!surface)
	return FALSE;

    vsrf = vmw_svga_winsys_surface(surface);
    whandle->handle = vsrf->sid;
    whandle->stride = stride;
    whandle->offset = 0;

    switch (whandle->type) {
    case DRM_API_HANDLE_TYPE_SHARED:
    case DRM_API_HANDLE_TYPE_KMS:
       whandle->handle = vsrf->sid;
       break;
    case DRM_API_HANDLE_TYPE_FD:
       ret = drmPrimeHandleToFD(vws->ioctl.drm_fd, vsrf->sid, DRM_CLOEXEC,
				(int *)&whandle->handle);
       if (ret) {
	  vmw_error("Failed to get file descriptor from prime.\n");
	  return FALSE;
       }
       break;
    default:
       vmw_error("Attempt to export unsupported handle type %d.\n",
		 whandle->type);
       return FALSE;
    }

    return TRUE;
}
Beispiel #8
0
void *
vmw_svga_winsys_surface_map(struct svga_winsys_context *swc,
                            struct svga_winsys_surface *srf,
                            unsigned flags, boolean *retry)
{
    struct vmw_svga_winsys_surface *vsrf = vmw_svga_winsys_surface(srf);
    void *data = NULL;
    struct pb_buffer *pb_buf;
    uint32_t pb_flags;
    struct vmw_winsys_screen *vws = vsrf->screen;

    *retry = FALSE;
    assert((flags & (PIPE_TRANSFER_READ | PIPE_TRANSFER_WRITE)) != 0);
    pipe_mutex_lock(vsrf->mutex);

    if (vsrf->mapcount) {
        /*
         * Only allow multiple readers to map.
         */
        if ((flags & PIPE_TRANSFER_WRITE) ||
                (vsrf->map_mode & PIPE_TRANSFER_WRITE))
            goto out_unlock;

        data = vsrf->data;
        goto out_mapped;
    }

    vsrf->rebind = FALSE;

    /*
     * If we intend to read, there's no point discarding the
     * data if busy.
     */
    if (flags & PIPE_TRANSFER_READ || vsrf->shared)
        flags &= ~PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;

    /*
     * Discard is a hint to a synchronized map.
     */
    if (flags & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE)
        flags &= ~PIPE_TRANSFER_UNSYNCHRONIZED;

    /*
     * The surface is allowed to be referenced on the command stream iff
     * we're mapping unsynchronized or discard. This is an early check.
     * We need to recheck after a failing discard map.
     */
    if (!(flags & (PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE |
                   PIPE_TRANSFER_UNSYNCHRONIZED)) &&
            p_atomic_read(&vsrf->validated)) {
        *retry = TRUE;
        goto out_unlock;
    }

    pb_flags = flags & (PIPE_TRANSFER_READ_WRITE | PIPE_TRANSFER_UNSYNCHRONIZED);

    if (flags & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
        struct pb_manager *provider;
        struct pb_desc desc;

        /*
         * First, if possible, try to map existing storage with DONTBLOCK.
         */
        if (!p_atomic_read(&vsrf->validated)) {
            data = vmw_svga_winsys_buffer_map(&vws->base, vsrf->buf,
                                              PIPE_TRANSFER_DONTBLOCK | pb_flags);
            if (data)
                goto out_mapped;
        }

        /*
         * Attempt to get a new buffer.
         */
        provider = vws->pools.mob_fenced;
        memset(&desc, 0, sizeof(desc));
        desc.alignment = 4096;
        pb_buf = provider->create_buffer(provider, vsrf->size, &desc);
        if (pb_buf != NULL) {
            struct svga_winsys_buffer *vbuf =
                vmw_svga_winsys_buffer_wrap(pb_buf);

            data = vmw_svga_winsys_buffer_map(&vws->base, vbuf, pb_flags);
            if (data) {
                vsrf->rebind = TRUE;
                /*
                 * We've discarded data on this surface and thus
                 * it's data is no longer consider referenced.
                 */
                vmw_swc_surface_clear_reference(swc, vsrf);
                if (vsrf->buf)
                    vmw_svga_winsys_buffer_destroy(&vws->base, vsrf->buf);
                vsrf->buf = vbuf;
                goto out_mapped;
            } else
                vmw_svga_winsys_buffer_destroy(&vws->base, vbuf);
        }
        /*
         * We couldn't get and map a new buffer for some reason.
         * Fall through to an ordinary map.
         * But tell pipe driver to flush now if already on validate list,
         * Otherwise we'll overwrite previous contents.
         */
        if (!(flags & PIPE_TRANSFER_UNSYNCHRONIZED) &&
                p_atomic_read(&vsrf->validated)) {
            *retry = TRUE;
            goto out_unlock;
        }
    }

    pb_flags |= (flags & PIPE_TRANSFER_DONTBLOCK);
    data = vmw_svga_winsys_buffer_map(&vws->base, vsrf->buf, pb_flags);
    if (data == NULL)
        goto out_unlock;

out_mapped:
    ++vsrf->mapcount;
    vsrf->data = data;
    vsrf->map_mode = flags & (PIPE_TRANSFER_READ | PIPE_TRANSFER_WRITE);
out_unlock:
    pipe_mutex_unlock(vsrf->mutex);
    return data;
}