@@ -269,6 +269,10 @@ struct i915_execbuffer {
*/
int lut_size;
struct hlist_head *buckets; /** ht for relocation handles */
+
+ struct {
+ u64 flags; /** Available extensions parameters */
+ } extensions;
};
#define exec_entry(EB, VMA) (&(EB)->exec[(VMA)->exec_flags - (EB)->flags])
@@ -1958,7 +1962,7 @@ static bool i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec)
return false;
/* Kernel clipping was a DRI1 misfeature */
- if (!(exec->flags & I915_EXEC_FENCE_ARRAY)) {
+ if (!(exec->flags & (I915_EXEC_FENCE_ARRAY | I915_EXEC_EXT))) {
if (exec->num_cliprects || exec->cliprects_ptr)
return false;
}
@@ -2336,6 +2340,42 @@ signal_fence_array(struct i915_execbuffer *eb,
}
}
+static int
+parse_execbuf2_extensions(struct drm_i915_gem_execbuffer2 *args,
+ struct i915_execbuffer *eb)
+{
+ u64 iter_ptr = args->cliprects_ptr;
+
+ if (args->num_cliprects != 0)
+ return -EINVAL;
+
+ while (iter_ptr != 0) {
+ struct drm_i915_gem_base_execbuffer_ext iter;
+
+ if (copy_from_user(&iter,
+ u64_to_user_ptr(iter_ptr), sizeof(iter)))
+ return -EFAULT;
+
+ if (iter.pad)
+ return -EINVAL;
+
+ /* Specifying the same extension multiple times is invalid. */
+ if (eb->extensions.flags & BIT(iter.type))
+ return -EINVAL;
+
+ switch (iter.type) {
+ default:
+ return -EINVAL;
+ }
+
+ eb->extensions.flags |= BIT(iter.type);
+
+ iter_ptr = iter.next_ptr;
+ }
+
+ return 0;
+}
+
static int
i915_gem_do_execbuffer(struct drm_device *dev,
struct drm_file *file,
@@ -2382,6 +2422,13 @@ i915_gem_do_execbuffer(struct drm_device *dev,
if (args->flags & I915_EXEC_IS_PINNED)
eb.batch_flags |= I915_DISPATCH_PINNED;
+ eb.extensions.flags = 0;
+ if (args->flags & I915_EXEC_EXT) {
+ err = parse_execbuf2_extensions(args, &eb);
+ if (err)
+ return err;
+ }
+
if (args->flags & I915_EXEC_FENCE_IN) {
in_fence = sync_file_get_fence(lower_32_bits(args->rsvd2));
if (!in_fence)
@@ -1013,6 +1013,29 @@ struct drm_i915_gem_exec_fence {
__u32 flags;
};
+enum drm_i915_gem_base_execbuffer_type {
+ DRM_I915_GEM_BASE_EXECBUFFER_TYPE_MAX /* non-ABI */
+};
+
+struct drm_i915_gem_base_execbuffer_ext {
+ /**
+ * Type of the extension node as limited in enum
+ * drm_i915_gem_base_execbuffer_type.
+ */
+ __u32 type;
+
+ /**
+ * Unused for now. Must be cleared to zero.
+ */
+ __u32 pad;
+
+ /**
+ * Pointer to another struct drm_i915_gem_base_execbuffer_ext or NULL
+ * to terminate the chain.
+ */
+ __u64 next_ptr;
+};
+
struct drm_i915_gem_execbuffer2 {
/**
* List of gem_exec_object2 structs
@@ -1029,8 +1052,14 @@ struct drm_i915_gem_execbuffer2 {
__u32 num_cliprects;
/**
* This is a struct drm_clip_rect *cliprects if I915_EXEC_FENCE_ARRAY
- * is not set. If I915_EXEC_FENCE_ARRAY is set, then this is a
- * struct drm_i915_gem_exec_fence *fences.
+ * & I915_EXEC_EXT are not set.
+ *
+ * If I915_EXEC_FENCE_ARRAY is set, then this is a pointer to an array
+ * of struct drm_i915_gem_exec_fence and num_cliprects is the length
+ * of the array.
+ *
+ * If I915_EXEC_EXT is set, then this is a pointer to a single struct
+ * drm_i915_gem_base_execbuffer_ext and num_cliprects is 0.
*/
__u64 cliprects_ptr;
#define I915_EXEC_RING_MASK (0x3f)
@@ -1148,7 +1177,16 @@ struct drm_i915_gem_execbuffer2 {
*/
#define I915_EXEC_FENCE_SUBMIT (1 << 20)
-#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SUBMIT << 1))
+/*
+ * Setting I915_EXEC_EXT implies that drm_i915_gem_execbuffer2.cliprects_ptr
+ * is treated as a pointer to an linked list of
+ * drm_i915_gem_base_execbuffer_ext. Each drm_i915_gem_base_execbuffer_ext
+ * node is the base of a larger structure. The list of supported structures
+ * are listed in the drm_i915_gem_base_execbuffer_type enum.
+ */
+#define I915_EXEC_EXT (1 << 21)
+
+#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_EXT<<1))
#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
#define i915_execbuffer2_set_context_id(eb2, context) \
We're planning to use this for a couple of new feature where we need to provide additional parameters to execbuf. Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> --- .../gpu/drm/i915/gem/i915_gem_execbuffer.c | 49 ++++++++++++++++++- include/uapi/drm/i915_drm.h | 44 +++++++++++++++-- 2 files changed, 89 insertions(+), 4 deletions(-)