|
@@ -1917,3 +1917,76 @@ err_ref:
|
|
|
vmw_resource_unreference(&res);
|
|
|
return ret;
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+int vmw_dumb_create(struct drm_file *file_priv,
|
|
|
+ struct drm_device *dev,
|
|
|
+ struct drm_mode_create_dumb *args)
|
|
|
+{
|
|
|
+ struct vmw_private *dev_priv = vmw_priv(dev);
|
|
|
+ struct vmw_master *vmaster = vmw_master(file_priv->master);
|
|
|
+ struct vmw_user_dma_buffer *vmw_user_bo;
|
|
|
+ struct ttm_buffer_object *tmp;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ args->pitch = args->width * ((args->bpp + 7) / 8);
|
|
|
+ args->size = args->pitch * args->height;
|
|
|
+
|
|
|
+ vmw_user_bo = kzalloc(sizeof(*vmw_user_bo), GFP_KERNEL);
|
|
|
+ if (vmw_user_bo == NULL)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ ret = ttm_read_lock(&vmaster->lock, true);
|
|
|
+ if (ret != 0) {
|
|
|
+ kfree(vmw_user_bo);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = vmw_dmabuf_init(dev_priv, &vmw_user_bo->dma, args->size,
|
|
|
+ &vmw_vram_sys_placement, true,
|
|
|
+ &vmw_user_dmabuf_destroy);
|
|
|
+ if (ret != 0)
|
|
|
+ goto out_no_dmabuf;
|
|
|
+
|
|
|
+ tmp = ttm_bo_reference(&vmw_user_bo->dma.base);
|
|
|
+ ret = ttm_base_object_init(vmw_fpriv(file_priv)->tfile,
|
|
|
+ &vmw_user_bo->base,
|
|
|
+ false,
|
|
|
+ ttm_buffer_type,
|
|
|
+ &vmw_user_dmabuf_release, NULL);
|
|
|
+ if (unlikely(ret != 0))
|
|
|
+ goto out_no_base_object;
|
|
|
+
|
|
|
+ args->handle = vmw_user_bo->base.hash.key;
|
|
|
+
|
|
|
+out_no_base_object:
|
|
|
+ ttm_bo_unref(&tmp);
|
|
|
+out_no_dmabuf:
|
|
|
+ ttm_read_unlock(&vmaster->lock);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+int vmw_dumb_map_offset(struct drm_file *file_priv,
|
|
|
+ struct drm_device *dev, uint32_t handle,
|
|
|
+ uint64_t *offset)
|
|
|
+{
|
|
|
+ struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
|
|
|
+ struct vmw_dma_buffer *out_buf;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ ret = vmw_user_dmabuf_lookup(tfile, handle, &out_buf);
|
|
|
+ if (ret != 0)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ *offset = out_buf->base.addr_space_offset;
|
|
|
+ vmw_dmabuf_unreference(&out_buf);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int vmw_dumb_destroy(struct drm_file *file_priv,
|
|
|
+ struct drm_device *dev,
|
|
|
+ uint32_t handle)
|
|
|
+{
|
|
|
+ return ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile,
|
|
|
+ handle, TTM_REF_USAGE);
|
|
|
+}
|