drm/i915/uapi: introduce drm_i915_gem_create_ext
authorMatthew Auld <matthew.auld@intel.com>
Thu, 29 Apr 2021 10:30:52 +0000 (11:30 +0100)
committerMatthew Auld <matthew.auld@intel.com>
Tue, 4 May 2021 09:58:56 +0000 (10:58 +0100)
Same old gem_create but with now with extensions support. This is needed
to support various upcoming usecases.

v2:(Chris)
    - Use separate ioctl number for gem_create_ext, instead of hijacking
      the existing gem_create ioctl, otherwise we run into the issue
      with being unable to detect if the kernel supports the new extension
      behaviour.
    - We now have gem_create_ext.flags, which should be zeroed.
    - I915_GEM_CREATE_EXT_SETPARAM value is now zero, since this is the
      index into our array of extensions.
    - Setup a "vanilla" object which we can directly apply our extensions
      to.
v3:(Daniel & Jason)
    - drop I915_GEM_CREATE_EXT_SETPARAM. Instead just have each extension
      do one thing only, instead of generic setparam which can cover
      various use cases.
    - add some kernel-doc.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: CQ Tang <cq.tang@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Lionel Landwerlin <lionel.g.landwerlin@linux.intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Kenneth Graunke <kenneth@whitecape.org>
Cc: Jason Ekstrand <jason@jlekstrand.net>
Cc: Dave Airlie <airlied@gmail.com>
Cc: dri-devel@lists.freedesktop.org
Cc: mesa-dev@lists.freedesktop.org
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20210429103056.407067-5-matthew.auld@intel.com
drivers/gpu/drm/i915/gem/i915_gem_create.c
drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
drivers/gpu/drm/i915/i915_drv.c
include/uapi/drm/i915_drm.h

index 409226d..1e82633 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "i915_drv.h"
 #include "i915_trace.h"
+#include "i915_user_extensions.h"
 
 static int i915_gem_publish(struct drm_i915_gem_object *obj,
                            struct drm_file *file,
@@ -149,3 +150,58 @@ object_free:
        i915_gem_object_free(obj);
        return ret;
 }
+
+struct create_ext {
+       struct drm_i915_private *i915;
+       struct drm_i915_gem_object *vanilla_object;
+};
+
+static const i915_user_extension_fn create_extensions[] = {
+};
+
+/**
+ * Creates a new mm object and returns a handle to it.
+ * @dev: drm device pointer
+ * @data: ioctl data blob
+ * @file: drm file pointer
+ */
+int
+i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
+                         struct drm_file *file)
+{
+       struct drm_i915_private *i915 = to_i915(dev);
+       struct drm_i915_gem_create_ext *args = data;
+       struct create_ext ext_data = { .i915 = i915 };
+       struct drm_i915_gem_object *obj;
+       int ret;
+
+       if (args->flags)
+               return -EINVAL;
+
+       i915_gem_flush_free_objects(i915);
+
+       obj = i915_gem_object_alloc();
+       if (!obj)
+               return -ENOMEM;
+
+       ext_data.vanilla_object = obj;
+       ret = i915_user_extensions(u64_to_user_ptr(args->extensions),
+                                  create_extensions,
+                                  ARRAY_SIZE(create_extensions),
+                                  &ext_data);
+       if (ret)
+               goto object_free;
+
+       ret = i915_gem_setup(obj,
+                            intel_memory_region_by_type(i915,
+                                                        INTEL_MEMORY_SYSTEM),
+                            args->size);
+       if (ret)
+               goto object_free;
+
+       return i915_gem_publish(obj, file, &args->size, &args->handle);
+
+object_free:
+       i915_gem_object_free(obj);
+       return ret;
+}
index 7fd22f3..28d6526 100644 (file)
@@ -14,6 +14,8 @@ int i915_gem_busy_ioctl(struct drm_device *dev, void *data,
                        struct drm_file *file);
 int i915_gem_create_ioctl(struct drm_device *dev, void *data,
                          struct drm_file *file);
+int i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
+                             struct drm_file *file);
 int i915_gem_execbuffer2_ioctl(struct drm_device *dev, void *data,
                               struct drm_file *file);
 int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
index 3286bcd..f50f7b4 100644 (file)
@@ -1705,6 +1705,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
        DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_RENDER_ALLOW),
+       DRM_IOCTL_DEF_DRV(I915_GEM_CREATE_EXT, i915_gem_create_ext_ioctl, DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_RENDER_ALLOW),
index 582ee6f..9ab609e 100644 (file)
@@ -406,6 +406,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_I915_QUERY                 0x39
 #define DRM_I915_GEM_VM_CREATE         0x3a
 #define DRM_I915_GEM_VM_DESTROY                0x3b
+#define DRM_I915_GEM_CREATE_EXT                0x3c
 /* Must be kept compact -- no holes */
 
 #define DRM_IOCTL_I915_INIT            DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
@@ -438,6 +439,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_GEM_ENTERVT     DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT)
 #define DRM_IOCTL_I915_GEM_LEAVEVT     DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT)
 #define DRM_IOCTL_I915_GEM_CREATE      DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create)
+#define DRM_IOCTL_I915_GEM_CREATE_EXT  DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE_EXT, struct drm_i915_gem_create_ext)
 #define DRM_IOCTL_I915_GEM_PREAD       DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
 #define DRM_IOCTL_I915_GEM_PWRITE      DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
 #define DRM_IOCTL_I915_GEM_MMAP                DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
@@ -2598,6 +2600,46 @@ struct drm_i915_query_memory_regions {
        struct drm_i915_memory_region_info regions[];
 };
 
+/**
+ * struct drm_i915_gem_create_ext - Existing gem_create behaviour, with added
+ * extension support using struct i915_user_extension.
+ *
+ * Note that in the future we want to have our buffer flags here, at least for
+ * the stuff that is immutable. Previously we would have two ioctls, one to
+ * create the object with gem_create, and another to apply various parameters,
+ * however this creates some ambiguity for the params which are considered
+ * immutable. Also in general we're phasing out the various SET/GET ioctls.
+ */
+struct drm_i915_gem_create_ext {
+       /**
+        * @size: Requested size for the object.
+        *
+        * The (page-aligned) allocated size for the object will be returned.
+        *
+        */
+       __u64 size;
+       /**
+        * @handle: Returned handle for the object.
+        *
+        * Object handles are nonzero.
+        */
+       __u32 handle;
+       /** @flags: MBZ */
+       __u32 flags;
+       /**
+        * @extensions: The chain of extensions to apply to this object.
+        *
+        * This will be useful in the future when we need to support several
+        * different extensions, and we need to apply more than one when
+        * creating the object. See struct i915_user_extension.
+        *
+        * If we don't supply any extensions then we get the same old gem_create
+        * behaviour.
+        *
+        */
+       __u64 extensions;
+};
+
 #if defined(__cplusplus)
 }
 #endif