vmwgfx: add dumb ioctl support
diff mbox

Message ID 1346118834-17339-1-git-send-email-airlied@gmail.com
State New, archived
Headers show

Commit Message

Dave Airlie Aug. 28, 2012, 1:53 a.m. UTC
From: Dave Airlie <airlied@redhat.com>

Testing and works with the -modesetting driver at least so far.

Signed-off-by: Dave Airlie <airlied@redhat.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c      |  5 +++
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h      | 10 +++++
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 73 ++++++++++++++++++++++++++++++++
 3 files changed, 88 insertions(+)

Comments

Jakob Bornecrantz Aug. 28, 2012, 3:06 p.m. UTC | #1
Thanks for doing this.

With an exception of a comment below all 3 patches are
Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>


----- Original Message -----
> From: Dave Airlie <airlied@redhat.com>
> 
> Testing and works with the -modesetting driver at least so far.
> 
> Signed-off-by: Dave Airlie <airlied@redhat.com>
> ---
>  drivers/gpu/drm/vmwgfx/vmwgfx_drv.c      |  5 +++
>  drivers/gpu/drm/vmwgfx/vmwgfx_drv.h      | 10 +++++
>  drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 73
>  ++++++++++++++++++++++++++++++++
>  3 files changed, 88 insertions(+)
> 
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> index 4d9edea..4d13bf7 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> @@ -1154,6 +1154,11 @@ static struct drm_driver driver = {
>  	.open = vmw_driver_open,
>  	.preclose = vmw_preclose,
>  	.postclose = vmw_postclose,
> +
> +	.dumb_create = vmw_dumb_create,
> +	.dumb_map_offset = vmw_dumb_map_offset,
> +	.dumb_destroy = vmw_dumb_destroy,
> +
>  	.fops = &vmwgfx_driver_fops,
>  	.name = VMWGFX_DRIVER_NAME,
>  	.desc = VMWGFX_DRIVER_DESC,
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
> b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
> index d0f2c07..29c984f 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
> @@ -645,6 +645,16 @@ int vmw_kms_readback(struct vmw_private
> *dev_priv,
>  int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
>  				struct drm_file *file_priv);
>  
> +int vmw_dumb_create(struct drm_file *file_priv,
> +		    struct drm_device *dev,
> +		    struct drm_mode_create_dumb *args);
> +
> +int vmw_dumb_map_offset(struct drm_file *file_priv,
> +			struct drm_device *dev, uint32_t handle,
> +			uint64_t *offset);
> +int vmw_dumb_destroy(struct drm_file *file_priv,
> +		     struct drm_device *dev,
> +		     uint32_t handle);
>  /**
>   * Overlay control - vmwgfx_overlay.c
>   */
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
> b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
> index 22bf9a2..5761775 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
> @@ -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 / 8;
> +	args->size = args->pitch * args->height;

We talked about this on IRC, it should probably be
(args->bpp + 7) / 8


Cheers, Jakob.

Patch
diff mbox

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 4d9edea..4d13bf7 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -1154,6 +1154,11 @@  static struct drm_driver driver = {
 	.open = vmw_driver_open,
 	.preclose = vmw_preclose,
 	.postclose = vmw_postclose,
+
+	.dumb_create = vmw_dumb_create,
+	.dumb_map_offset = vmw_dumb_map_offset,
+	.dumb_destroy = vmw_dumb_destroy,
+
 	.fops = &vmwgfx_driver_fops,
 	.name = VMWGFX_DRIVER_NAME,
 	.desc = VMWGFX_DRIVER_DESC,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index d0f2c07..29c984f 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -645,6 +645,16 @@  int vmw_kms_readback(struct vmw_private *dev_priv,
 int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
 				struct drm_file *file_priv);
 
+int vmw_dumb_create(struct drm_file *file_priv,
+		    struct drm_device *dev,
+		    struct drm_mode_create_dumb *args);
+
+int vmw_dumb_map_offset(struct drm_file *file_priv,
+			struct drm_device *dev, uint32_t handle,
+			uint64_t *offset);
+int vmw_dumb_destroy(struct drm_file *file_priv,
+		     struct drm_device *dev,
+		     uint32_t handle);
 /**
  * Overlay control - vmwgfx_overlay.c
  */
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
index 22bf9a2..5761775 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
@@ -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 / 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);
+}