hack
authorMateusz Majewski <m.majewski2@samsung.com>
Fri, 12 Apr 2024 12:42:56 +0000 (14:42 +0200)
committerMateusz Majewski <m.majewski2@samsung.com>
Tue, 28 May 2024 09:02:57 +0000 (11:02 +0200)
drivers/gpu/drm/virtio/virtgpu_drv.h
drivers/gpu/drm/virtio/virtgpu_fb.c
drivers/gpu/drm/virtio/virtgpu_gem.c
drivers/gpu/drm/virtio/virtgpu_ioctl.c
drivers/gpu/drm/virtio/virtgpu_object.c
include/uapi/drm/virtgpu_drm.h

index 79f0abe69b6476962e33d82c14745c25e9263693..da572a7ebef292cce75893967a49bbd87e75ba0d 100644 (file)
@@ -62,6 +62,8 @@ struct virtio_gpu_object {
        struct ttm_placement            placement;
        struct ttm_buffer_object        tbo;
        struct ttm_bo_kmap_obj          kmap;
+
+       uint32_t width, height, format;
 };
 #define gem_to_virtio_gpu_obj(gobj) \
        container_of((gobj), struct virtio_gpu_object, gem_base)
@@ -208,7 +210,7 @@ struct virtio_gpu_fpriv {
 };
 
 /* virtio_ioctl.c */
-#define DRM_VIRTIO_NUM_IOCTLS 10
+#define DRM_VIRTIO_NUM_IOCTLS 11
 extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS];
 
 /* virtio_kms.c */
@@ -221,10 +223,9 @@ void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file);
 void virtio_gpu_gem_free_object(struct drm_gem_object *gem_obj);
 int virtio_gpu_gem_init(struct virtio_gpu_device *vgdev);
 void virtio_gpu_gem_fini(struct virtio_gpu_device *vgdev);
-int virtio_gpu_gem_create(struct drm_file *file,
-                         struct drm_device *dev,
-                         uint64_t size,
-                         struct drm_gem_object **obj_p,
+int virtio_gpu_gem_create(struct drm_file *file, struct drm_device *dev,
+                         uint64_t size, uint32_t width, uint32_t height,
+                         uint32_t format, struct drm_gem_object **obj_p,
                          uint32_t *handle_p);
 int virtio_gpu_gem_object_open(struct drm_gem_object *obj,
                               struct drm_file *file);
@@ -232,7 +233,9 @@ void virtio_gpu_gem_object_close(struct drm_gem_object *obj,
                                 struct drm_file *file);
 struct virtio_gpu_object *virtio_gpu_alloc_object(struct drm_device *dev,
                                                  size_t size, bool kernel,
-                                                 bool pinned);
+                                                 bool pinned, uint32_t width,
+                                                 uint32_t height,
+                                                 uint32_t format);
 int virtio_gpu_mode_dumb_create(struct drm_file *file_priv,
                                struct drm_device *dev,
                                struct drm_mode_create_dumb *args);
@@ -352,6 +355,7 @@ void virtio_gpu_fence_event_process(struct virtio_gpu_device *vdev,
 /* virtio_gpu_object */
 int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
                             unsigned long size, bool kernel, bool pinned,
+                            uint32_t width, uint32_t height, uint32_t format,
                             struct virtio_gpu_object **bo_ptr);
 int virtio_gpu_object_kmap(struct virtio_gpu_object *bo, void **ptr);
 int virtio_gpu_object_get_sg_table(struct virtio_gpu_device *qdev,
index 6a81e084593bde8539197f417cb72e56498ced22..09d7825db4ef561edc4ba9ceafd993cdee2d2f6b 100644 (file)
@@ -297,7 +297,8 @@ static int virtio_gpufb_create(struct drm_fb_helper *helper,
        }
 
        size = mode_cmd.pitches[0] * mode_cmd.height;
-       obj = virtio_gpu_alloc_object(dev, size, false, true);
+       obj = virtio_gpu_alloc_object(dev, size, false, true, mode_cmd.width,
+                                     mode_cmd.height, format);
        if (IS_ERR(obj))
                return PTR_ERR(obj);
 
index 1feb7cee3f0d7a713dc06621cf1e41740da301af..2189674d3812d5ced2bff1885f29852fc31f5911 100644 (file)
@@ -36,30 +36,33 @@ void virtio_gpu_gem_free_object(struct drm_gem_object *gem_obj)
 
 struct virtio_gpu_object *virtio_gpu_alloc_object(struct drm_device *dev,
                                                  size_t size, bool kernel,
-                                                 bool pinned)
+                                                 bool pinned, uint32_t width,
+                                                 uint32_t height,
+                                                 uint32_t format)
 {
        struct virtio_gpu_device *vgdev = dev->dev_private;
        struct virtio_gpu_object *obj;
        int ret;
 
-       ret = virtio_gpu_object_create(vgdev, size, kernel, pinned, &obj);
+       ret = virtio_gpu_object_create(vgdev, size, kernel, pinned, width,
+                                      height, format, &obj);
        if (ret)
                return ERR_PTR(ret);
 
        return obj;
 }
 
-int virtio_gpu_gem_create(struct drm_file *file,
-                         struct drm_device *dev,
-                         uint64_t size,
-                         struct drm_gem_object **obj_p,
+int virtio_gpu_gem_create(struct drm_file *file, struct drm_device *dev,
+                         uint64_t size, uint32_t width, uint32_t height,
+                         uint32_t format, struct drm_gem_object **obj_p,
                          uint32_t *handle_p)
 {
        struct virtio_gpu_object *obj;
        int ret;
        u32 handle;
 
-       obj = virtio_gpu_alloc_object(dev, size, false, false);
+       obj = virtio_gpu_alloc_object(dev, size, false, false, width, height,
+                                     format);
        if (IS_ERR(obj))
                return PTR_ERR(obj);
 
@@ -93,8 +96,8 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv,
        args->size = pitch * args->height;
        args->size = ALIGN(args->size, PAGE_SIZE);
 
-       ret = virtio_gpu_gem_create(file_priv, dev, args->size, &gobj,
-                                   &args->handle);
+       ret = virtio_gpu_gem_create(file_priv, dev, args->size, args->width,
+                                   args->height, 2, &gobj, &args->handle);
        if (ret)
                goto fail;
 
index b4de18e65db8d5b87dbbe5b9136d957a32cae7f0..e71560e9fe51cc6611c3a990bd17c20df72f244d 100644 (file)
@@ -259,7 +259,8 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
        if (size == 0)
                size = PAGE_SIZE;
 
-       qobj = virtio_gpu_alloc_object(dev, size, false, false);
+       qobj = virtio_gpu_alloc_object(dev, size, false, false, rc->width,
+                                      rc->height, rc->format);
        if (IS_ERR(qobj)) {
                ret = PTR_ERR(qobj);
                goto fail_id;
@@ -539,6 +540,45 @@ copy_exit:
        return 0;
 }
 
+static int virtio_gpu_brutal_hack(struct drm_device *dev, void *data,
+                                 struct drm_file *file)
+{
+       struct drm_virtgpu_brutal_hack *bh = data;
+       struct drm_gem_object *gobj = NULL;
+       struct virtio_gpu_object *qobj = NULL;
+
+       gobj = drm_gem_object_lookup(dev, file, bh->bo_handle);
+       if (gobj == NULL) {
+               return -ENOENT;
+       }
+
+       qobj = gem_to_virtio_gpu_obj(gobj);
+
+       bh->width = qobj->width;
+       bh->height = qobj->height;
+       bh->pitch = qobj->width * 4;
+       switch (qobj->format) {
+       case VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM:
+               bh->format = DRM_FORMAT_XRGB8888;
+               break;
+       case VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM:
+               bh->format = DRM_FORMAT_ARGB8888;
+               break;
+       case VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM:
+               bh->format = DRM_FORMAT_BGRX8888;
+               break;
+       case VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM:
+               bh->format = DRM_FORMAT_BGRA8888;
+               break;
+       default:
+               bh->format = 0;
+               break;
+       }
+
+       drm_gem_object_unreference_unlocked(gobj);
+       return 0;
+}
+
 struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS] = {
        DRM_IOCTL_DEF_DRV(VIRTGPU_MAP, virtio_gpu_map_ioctl,
                          DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
@@ -570,4 +610,7 @@ struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS] = {
 
        DRM_IOCTL_DEF_DRV(VIRTGPU_GET_CAPS, virtio_gpu_get_caps_ioctl,
                          DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
+
+       DRM_IOCTL_DEF_DRV(VIRTGPU_BRUTAL_HACK, virtio_gpu_brutal_hack,
+                         DRM_RENDER_ALLOW),
 };
index f300eba95bb1bff32ad8e9be2a8250779ec255b6..e591c68bdbb9f908683057bd73b0d2b4fb6f3de7 100644 (file)
@@ -60,6 +60,7 @@ static void virtio_gpu_init_ttm_placement(struct virtio_gpu_object *vgbo,
 
 int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
                             unsigned long size, bool kernel, bool pinned,
+                            uint32_t width, uint32_t height, uint32_t format,
                             struct virtio_gpu_object **bo_ptr)
 {
        struct virtio_gpu_object *bo;
@@ -93,6 +94,10 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
        if (ret != 0)
                return ret;
 
+       bo->width = width;
+       bo->height = height;
+       bo->format = format;
+
        *bo_ptr = bo;
        return 0;
 }
index fc9e2d6e5e2f55a05590d7a962813a901dae7040..81a50d6d08b72c9dc1b246232a1b16d85db892e3 100644 (file)
@@ -43,6 +43,7 @@
 #define DRM_VIRTGPU_TRANSFER_TO_HOST 0x07
 #define DRM_VIRTGPU_WAIT     0x08
 #define DRM_VIRTGPU_GET_CAPS  0x09
+#define DRM_VIRTGPU_BRUTAL_HACK 0x0A
 
 struct drm_virtgpu_map {
        uint64_t offset; /* use for mmap system call */
@@ -129,6 +130,14 @@ struct drm_virtgpu_get_caps {
        uint32_t pad;
 };
 
+struct drm_virtgpu_brutal_hack {
+       __u32 bo_handle;
+       __u32 width;
+       __u32 height;
+       __u32 pitch;
+       __u32 format;
+};
+
 #define DRM_IOCTL_VIRTGPU_MAP \
        DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_MAP, struct drm_virtgpu_map)
 
@@ -164,4 +173,8 @@ struct drm_virtgpu_get_caps {
        DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_GET_CAPS, \
        struct drm_virtgpu_get_caps)
 
+#define DRM_IOCTL_VIRTGPU_BRUTAL_HACK \
+       DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_BRUTAL_HACK, \
+       struct drm_virtgpu_brutal_hack)
+
 #endif