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.
Unified · Split
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | |
| 9 | 9 | #include "i915_drv.h" |
| 10 | 10 | #include "i915_trace.h" |
| 11 | +#include "i915_user_extensions.h" | |
| 11 | 12 | |
| 12 | 13 | static int i915_gem_publish(struct drm_i915_gem_object *obj, |
| 13 | 14 | struct drm_file *file, |
| @@ -149,3 +150,58 @@ object_free: · 135 unmodified lines | ||
| 149 | 150 | i915_gem_object_free(obj); |
| 150 | 151 | return ret; |
| 151 | 152 | } |
| 153 | + | |
| 154 | +struct create_ext { | |
| 155 | + struct drm_i915_private *i915; | |
| 156 | + struct drm_i915_gem_object *vanilla_object; | |
| 157 | +}; | |
| 158 | + | |
| 159 | +static const i915_user_extension_fn create_extensions[] = { | |
| 160 | +}; | |
| 161 | + | |
| 162 | +/** | |
| 163 | + * Creates a new mm object and returns a handle to it. | |
| 164 | + * @dev: drm device pointer | |
| 165 | + * @data: ioctl data blob | |
| 166 | + * @file: drm file pointer | |
| 167 | + */ | |
| 168 | +int | |
| 169 | +i915_gem_create_ext_ioctl(struct drm_device *dev, void *data, | |
| 170 | + struct drm_file *file) | |
| 171 | +{ | |
| 172 | + struct drm_i915_private *i915 = to_i915(dev); | |
| 173 | + struct drm_i915_gem_create_ext *args = data; | |
| 174 | + struct create_ext ext_data = { .i915 = i915 }; | |
| 175 | + struct drm_i915_gem_object *obj; | |
| 176 | + int ret; | |
| 177 | + | |
| 178 | + if (args->flags) | |
| 179 | + return -EINVAL; | |
| 180 | + | |
| 181 | + i915_gem_flush_free_objects(i915); | |
| 182 | + | |
| 183 | + obj = i915_gem_object_alloc(); | |
| 184 | + if (!obj) | |
| 185 | + return -ENOMEM; | |
| 186 | + | |
| 187 | + ext_data.vanilla_object = obj; | |
| 188 | + ret = i915_user_extensions(u64_to_user_ptr(args->extensions), | |
| 189 | + create_extensions, | |
| 190 | + ARRAY_SIZE(create_extensions), | |
| 191 | + &ext_data); | |
| 192 | + if (ret) | |
| 193 | + goto object_free; | |
| 194 | + | |
| 195 | + ret = i915_gem_setup(obj, | |
| 196 | + intel_memory_region_by_type(i915, | |
| 197 | + INTEL_MEMORY_SYSTEM), | |
| 198 | + args->size); | |
| 199 | + if (ret) | |
| 200 | + goto object_free; | |
| 201 | + | |
| 202 | + return i915_gem_publish(obj, file, &args->size, &args->handle); | |
| 203 | + | |
| 204 | +object_free: | |
| 205 | + i915_gem_object_free(obj); | |
| 206 | + return ret; | |
| 207 | +} | |
| @@ -14,6 +14,8 @@ int i915_gem_busy_ioctl(struct drm_device *dev, void *data, · 13 unmodified lines | ||
| 14 | 14 | struct drm_file *file); |
| 15 | 15 | int i915_gem_create_ioctl(struct drm_device *dev, void *data, |
| 16 | 16 | struct drm_file *file); |
| 17 | +int i915_gem_create_ext_ioctl(struct drm_device *dev, void *data, | |
| 18 | + struct drm_file *file); | |
| 17 | 19 | int i915_gem_execbuffer2_ioctl(struct drm_device *dev, void *data, |
| 18 | 20 | struct drm_file *file); |
| 19 | 21 | int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, |
| @@ -1705,6 +1705,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = { · 1704 unmodified lines | ||
| 1705 | 1705 | DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 1706 | 1706 | DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 1707 | 1707 | DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_RENDER_ALLOW), |
| 1708 | + DRM_IOCTL_DEF_DRV(I915_GEM_CREATE_EXT, i915_gem_create_ext_ioctl, DRM_RENDER_ALLOW), | |
| 1708 | 1709 | DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_RENDER_ALLOW), |
| 1709 | 1710 | DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_RENDER_ALLOW), |
| 1710 | 1711 | DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_RENDER_ALLOW), |
| @@ -406,6 +406,7 @@ typedef struct _drm_i915_sarea { · 405 unmodified lines | ||
| 406 | 406 | #define DRM_I915_QUERY 0x39 |
| 407 | 407 | #define DRM_I915_GEM_VM_CREATE 0x3a |
| 408 | 408 | #define DRM_I915_GEM_VM_DESTROY 0x3b |
| 409 | +#define DRM_I915_GEM_CREATE_EXT 0x3c | |
| 409 | 410 | /* Must be kept compact -- no holes */ |
| 410 | 411 | |
| 411 | 412 | #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 { · 26 unmodified lines | ||
| 438 | 439 | #define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT) |
| 439 | 440 | #define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT) |
| 440 | 441 | #define DRM_IOCTL_I915_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create) |
| 442 | +#define DRM_IOCTL_I915_GEM_CREATE_EXT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE_EXT, struct drm_i915_gem_create_ext) | |
| 441 | 443 | #define DRM_IOCTL_I915_GEM_PREAD DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread) |
| 442 | 444 | #define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite) |
| 443 | 445 | #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 { · 2154 unmodified lines | ||
| 2598 | 2600 | struct drm_i915_memory_region_info regions[]; |
| 2599 | 2601 | }; |
| 2600 | 2602 | |
| 2603 | +/** | |
| 2604 | + * struct drm_i915_gem_create_ext - Existing gem_create behaviour, with added | |
| 2605 | + * extension support using struct i915_user_extension. | |
| 2606 | + * | |
| 2607 | + * Note that in the future we want to have our buffer flags here, at least for | |
| 2608 | + * the stuff that is immutable. Previously we would have two ioctls, one to | |
| 2609 | + * create the object with gem_create, and another to apply various parameters, | |
| 2610 | + * however this creates some ambiguity for the params which are considered | |
| 2611 | + * immutable. Also in general we're phasing out the various SET/GET ioctls. | |
| 2612 | + */ | |
| 2613 | +struct drm_i915_gem_create_ext { | |
| 2614 | + /** | |
| 2615 | + * @size: Requested size for the object. | |
| 2616 | + * | |
| 2617 | + * The (page-aligned) allocated size for the object will be returned. | |
| 2618 | + * | |
| 2619 | + */ | |
| 2620 | + __u64 size; | |
| 2621 | + /** | |
| 2622 | + * @handle: Returned handle for the object. | |
| 2623 | + * | |
| 2624 | + * Object handles are nonzero. | |
| 2625 | + */ | |
| 2626 | + __u32 handle; | |
| 2627 | + /** @flags: MBZ */ | |
| 2628 | + __u32 flags; | |
| 2629 | + /** | |
| 2630 | + * @extensions: The chain of extensions to apply to this object. | |
| 2631 | + * | |
| 2632 | + * This will be useful in the future when we need to support several | |
| 2633 | + * different extensions, and we need to apply more than one when | |
| 2634 | + * creating the object. See struct i915_user_extension. | |
| 2635 | + * | |
| 2636 | + * If we don't supply any extensions then we get the same old gem_create | |
| 2637 | + * behaviour. | |
| 2638 | + * | |
| 2639 | + */ | |
| 2640 | + __u64 extensions; | |
| 2641 | +}; | |
| 2642 | + | |
| 2601 | 2643 | #if defined(__cplusplus) |
| 2602 | 2644 | } |
| 2603 | 2645 | #endif |