linux/drivers/gpu/drm/virtio/virtgpu_gem.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2015 Red Hat, Inc.
   3 * All Rights Reserved.
   4 *
   5 * Permission is hereby granted, free of charge, to any person obtaining
   6 * a copy of this software and associated documentation files (the
   7 * "Software"), to deal in the Software without restriction, including
   8 * without limitation the rights to use, copy, modify, merge, publish,
   9 * distribute, sublicense, and/or sell copies of the Software, and to
  10 * permit persons to whom the Software is furnished to do so, subject to
  11 * the following conditions:
  12 *
  13 * The above copyright notice and this permission notice (including the
  14 * next paragraph) shall be included in all copies or substantial
  15 * portions of the Software.
  16 *
  17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
  21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24 */
  25
  26#include <drm/drmP.h>
  27#include "virtgpu_drv.h"
  28
  29void virtio_gpu_gem_free_object(struct drm_gem_object *gem_obj)
  30{
  31        struct virtio_gpu_object *obj = gem_to_virtio_gpu_obj(gem_obj);
  32
  33        if (obj)
  34                virtio_gpu_object_unref(&obj);
  35}
  36
  37struct virtio_gpu_object *virtio_gpu_alloc_object(struct drm_device *dev,
  38                                                  size_t size, bool kernel,
  39                                                  bool pinned)
  40{
  41        struct virtio_gpu_device *vgdev = dev->dev_private;
  42        struct virtio_gpu_object *obj;
  43        int ret;
  44
  45        ret = virtio_gpu_object_create(vgdev, size, kernel, pinned, &obj);
  46        if (ret)
  47                return ERR_PTR(ret);
  48
  49        return obj;
  50}
  51
  52int virtio_gpu_gem_create(struct drm_file *file,
  53                          struct drm_device *dev,
  54                          uint64_t size,
  55                          struct drm_gem_object **obj_p,
  56                          uint32_t *handle_p)
  57{
  58        struct virtio_gpu_object *obj;
  59        int ret;
  60        u32 handle;
  61
  62        obj = virtio_gpu_alloc_object(dev, size, false, false);
  63        if (IS_ERR(obj))
  64                return PTR_ERR(obj);
  65
  66        ret = drm_gem_handle_create(file, &obj->gem_base, &handle);
  67        if (ret) {
  68                drm_gem_object_release(&obj->gem_base);
  69                return ret;
  70        }
  71
  72        *obj_p = &obj->gem_base;
  73
  74        /* drop reference from allocate - handle holds it now */
  75        drm_gem_object_unreference_unlocked(&obj->gem_base);
  76
  77        *handle_p = handle;
  78        return 0;
  79}
  80
  81int virtio_gpu_mode_dumb_create(struct drm_file *file_priv,
  82                                struct drm_device *dev,
  83                                struct drm_mode_create_dumb *args)
  84{
  85        struct virtio_gpu_device *vgdev = dev->dev_private;
  86        struct drm_gem_object *gobj;
  87        struct virtio_gpu_object *obj;
  88        int ret;
  89        uint32_t pitch;
  90        uint32_t resid;
  91
  92        pitch = args->width * ((args->bpp + 1) / 8);
  93        args->size = pitch * args->height;
  94        args->size = ALIGN(args->size, PAGE_SIZE);
  95
  96        ret = virtio_gpu_gem_create(file_priv, dev, args->size, &gobj,
  97                                    &args->handle);
  98        if (ret)
  99                goto fail;
 100
 101        virtio_gpu_resource_id_get(vgdev, &resid);
 102        virtio_gpu_cmd_create_resource(vgdev, resid,
 103                                       2, args->width, args->height);
 104
 105        /* attach the object to the resource */
 106        obj = gem_to_virtio_gpu_obj(gobj);
 107        ret = virtio_gpu_object_attach(vgdev, obj, resid, NULL);
 108        if (ret)
 109                goto fail;
 110
 111        obj->dumb = true;
 112        args->pitch = pitch;
 113        return ret;
 114
 115fail:
 116        return ret;
 117}
 118
 119int virtio_gpu_mode_dumb_destroy(struct drm_file *file_priv,
 120                                 struct drm_device *dev,
 121                                 uint32_t handle)
 122{
 123        return drm_gem_handle_delete(file_priv, handle);
 124}
 125
 126int virtio_gpu_mode_dumb_mmap(struct drm_file *file_priv,
 127                              struct drm_device *dev,
 128                              uint32_t handle, uint64_t *offset_p)
 129{
 130        struct drm_gem_object *gobj;
 131        struct virtio_gpu_object *obj;
 132        BUG_ON(!offset_p);
 133        gobj = drm_gem_object_lookup(dev, file_priv, handle);
 134        if (gobj == NULL)
 135                return -ENOENT;
 136        obj = gem_to_virtio_gpu_obj(gobj);
 137        *offset_p = virtio_gpu_object_mmap_offset(obj);
 138        drm_gem_object_unreference_unlocked(gobj);
 139        return 0;
 140}
 141
 142int virtio_gpu_gem_object_open(struct drm_gem_object *obj,
 143                               struct drm_file *file)
 144{
 145        struct virtio_gpu_device *vgdev = obj->dev->dev_private;
 146        struct virtio_gpu_fpriv *vfpriv = file->driver_priv;
 147        struct virtio_gpu_object *qobj = gem_to_virtio_gpu_obj(obj);
 148        int r;
 149
 150        if (!vgdev->has_virgl_3d)
 151                return 0;
 152
 153        r = virtio_gpu_object_reserve(qobj, false);
 154        if (r)
 155                return r;
 156
 157        virtio_gpu_cmd_context_attach_resource(vgdev, vfpriv->ctx_id,
 158                                               qobj->hw_res_handle);
 159        virtio_gpu_object_unreserve(qobj);
 160        return 0;
 161}
 162
 163void virtio_gpu_gem_object_close(struct drm_gem_object *obj,
 164                                 struct drm_file *file)
 165{
 166        struct virtio_gpu_device *vgdev = obj->dev->dev_private;
 167        struct virtio_gpu_fpriv *vfpriv = file->driver_priv;
 168        struct virtio_gpu_object *qobj = gem_to_virtio_gpu_obj(obj);
 169        int r;
 170
 171        if (!vgdev->has_virgl_3d)
 172                return;
 173
 174        r = virtio_gpu_object_reserve(qobj, false);
 175        if (r)
 176                return;
 177
 178        virtio_gpu_cmd_context_detach_resource(vgdev, vfpriv->ctx_id,
 179                                                qobj->hw_res_handle);
 180        virtio_gpu_object_unreserve(qobj);
 181}
 182