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 | #include "i915_drv.h" | 9 | #include "i915_drv.h" |
| 10 | #include "i915_trace.h" | 10 | #include "i915_trace.h" |
| 11 | #include "i915_user_extensions.h" | ||
| 11 | 12 | ||
| 12 | static int i915_gem_publish(struct drm_i915_gem_object *obj, | 13 | static int i915_gem_publish(struct drm_i915_gem_object *obj, |
| 13 | struct drm_file *file, | 14 | struct drm_file *file, |
| @@ -149,3 +150,58 @@ object_free: · 135 unmodified lines | |||
| 149 | i915_gem_object_free(obj); | 150 | i915_gem_object_free(obj); |
| 150 | return ret; | 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 | struct drm_file *file); | 14 | struct drm_file *file); |
| 15 | int i915_gem_create_ioctl(struct drm_device *dev, void *data, | 15 | int i915_gem_create_ioctl(struct drm_device *dev, void *data, |
| 16 | struct drm_file *file); | 16 | struct drm_file *file); |
| 17 | int i915_gem_create_ext_ioctl(struct drm_device *dev, void *data, | ||
| 18 | struct drm_file *file); | ||
| 17 | int i915_gem_execbuffer2_ioctl(struct drm_device *dev, void *data, | 19 | int i915_gem_execbuffer2_ioctl(struct drm_device *dev, void *data, |
| 18 | struct drm_file *file); | 20 | struct drm_file *file); |
| 19 | int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, | 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 | DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1705 | DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 1706 | DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1706 | DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 1707 | DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_RENDER_ALLOW), | 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 | DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_RENDER_ALLOW), | 1709 | DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_RENDER_ALLOW), |
| 1709 | DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_RENDER_ALLOW), | 1710 | DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_RENDER_ALLOW), |
| 1710 | DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_RENDER_ALLOW), | 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 | #define DRM_I915_QUERY 0x39 | 406 | #define DRM_I915_QUERY 0x39 |
| 407 | #define DRM_I915_GEM_VM_CREATE 0x3a | 407 | #define DRM_I915_GEM_VM_CREATE 0x3a |
| 408 | #define DRM_I915_GEM_VM_DESTROY 0x3b | 408 | #define DRM_I915_GEM_VM_DESTROY 0x3b |
| 409 | #define DRM_I915_GEM_CREATE_EXT 0x3c | ||
| 409 | /* Must be kept compact -- no holes */ | 410 | /* Must be kept compact -- no holes */ |
| 410 | 411 | ||
| 411 | #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) | 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 | #define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT) | 439 | #define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT) |
| 439 | #define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT) | 440 | #define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT) |
| 440 | #define DRM_IOCTL_I915_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create) | 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 | #define DRM_IOCTL_I915_GEM_PREAD DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread) | 443 | #define DRM_IOCTL_I915_GEM_PREAD DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread) |
| 442 | #define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite) | 444 | #define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite) |
| 443 | #define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap) | 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 | struct drm_i915_memory_region_info regions[]; | 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 | #if defined(__cplusplus) | 2643 | #if defined(__cplusplus) |
| 2602 | } | 2644 | } |
| 2603 | #endif | 2645 | #endif |