[Intel-gfx] [PATCH 4/8] drm/i915/context: minimal support for contexts in execbuffer2

Ben Widawsky bwidawsk at gmail.com
Thu Feb 3 00:00:16 CET 2011


This change doesn't do anything except take parameters from clients
for context flag information, and pass it to a stubbed function to
validate the context flag information.

Included here are the updates to the necessary functions and structures
needed to handle contexts when execbuffer is called. It seems we are
able to reuse the rsvd1 and rsvd2 fields and not need a new ioctl for
this.

Renamed ctx to context in many places to avoid confusion with drm
contexts which seem unrelated.
---
 drivers/gpu/drm/i915/i915_context.c        |   11 +++++--
 drivers/gpu/drm/i915/i915_drv.h            |    5 +++
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |   45 +++++++++++++++++++++++++--
 include/drm/i915_drm.h                     |   15 +++++++++
 4 files changed, 69 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_context.c b/drivers/gpu/drm/i915/i915_context.c
index dec3b02..dac09be 100644
--- a/drivers/gpu/drm/i915/i915_context.c
+++ b/drivers/gpu/drm/i915/i915_context.c
@@ -59,14 +59,19 @@ i915_context_lookup_id(struct drm_device *dev,
 	return idr_find(&dev_priv->i915_ctx_idr, id);
 }
 
-static void
-i915_context_del_id(struct drm_device *dev,
-		    struct drm_i915_gem_context *ctx)
+static void i915_context_del_id(struct drm_device *dev,
+				struct drm_i915_gem_context *ctx)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	idr_remove(&dev_priv->i915_ctx_idr, ctx->ctx_id);
 }
 
+int i915_context_validate(struct drm_device *dev, struct drm_file *file,
+			  uint32_t ctx_id,
+			  struct drm_i915_context_flag *ctx_flag, int count)
+{
+	return 0;
+}
 /**
  * i915_context_alloc_backing_obj - Allocate and pin space in the global GTT for
  * use by the HW to save, and restore context information.
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 15635dd..d21b125 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1320,6 +1320,11 @@ extern void intel_display_print_error_state(struct seq_file *m,
 extern void i915_context_init(struct drm_device *dev);
 extern void i915_context_fini(struct drm_device *dev);
 extern void i915_context_close(struct drm_device *dev, struct drm_file *file);
+struct drm_i915_context_flag;
+extern int i915_context_validate(struct drm_device *dev,
+				 struct drm_file *file, uint32_t ctx_id,
+				 struct drm_i915_context_flag *ctx_flag,
+				 int count);
 
 #define LP_RING(d) (&((struct drm_i915_private *)(d))->ring[RCS])
 
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index d2f445e..a60996d 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -979,7 +979,9 @@ static int
 i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 		       struct drm_file *file,
 		       struct drm_i915_gem_execbuffer2 *args,
-		       struct drm_i915_gem_exec_object2 *exec)
+		       struct drm_i915_gem_exec_object2 *exec,
+		       struct drm_i915_context_flag *ctx_flags,
+		       int flag_count)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	struct list_head objects;
@@ -999,7 +1001,15 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 	ret = validate_exec_list(exec, args->buffer_count);
 	if (ret)
 		return ret;
-
+	if (ctx_flags) {
+		ret = i915_context_validate(dev, file, EXECBUFFER2_CTX_ID(args),
+					    ctx_flags, flag_count);
+		if (ret) {
+			if (ret == -EAGAIN)
+				DRM_DEBUG_DRIVER("Context resubmission required\n");
+			return ret;
+		}
+	}
 #if WATCH_EXEC
 	DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
 		  (int) args->buffers_ptr, args->buffer_count, args->batch_len);
@@ -1299,7 +1309,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
 	exec2.cliprects_ptr = args->cliprects_ptr;
 	exec2.flags = I915_EXEC_RENDER;
 
-	ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list);
+	ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list,
+				     NULL, 0);
 	if (!ret) {
 		/* Copy the new buffer offsets back to the user's exec list. */
 		for (i = 0; i < args->buffer_count; i++)
@@ -1328,6 +1339,8 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
 {
 	struct drm_i915_gem_execbuffer2 *args = data;
 	struct drm_i915_gem_exec_object2 *exec2_list = NULL;
+	struct drm_i915_context_flag *flags = NULL;
+	uint32_t flag_count = 0;
 	int ret;
 
 #if WATCH_EXEC
@@ -1356,8 +1369,32 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
 		drm_free_large(exec2_list);
 		return -EFAULT;
 	}
+	if (EXECBUFFER2_FLAGS_PTR(args) && EXECBUFFER2_FLAGS_COUNT(argc)) {
+		flag_count = EXECBUFFER2_FLAGS_COUNT(argc);
+		flags = drm_malloc_ab(sizeof(*flags), flag_count);
+		if (flags == NULL) {
+			DRM_ERROR("allocation of flags failed\n");
+			drm_free_large(exec2_list);
+			/*  return -EAGAIN; */
+			return -ENOMEM;
+		}
 
-	ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list);
+		ret = copy_from_user(flags,
+				     (struct drm_context_flags __user *)
+				     (uintptr_t)EXECBUFFER2_FLAGS_PTR(args),
+				     sizeof(*flags) * flag_count);
+		if (ret != 0) {
+			DRM_ERROR("copy %d flags failed %d\n",
+				  flag_count, ret);
+			drm_free_large(flags);
+			drm_free_large(exec2_list);
+			return -EFAULT;
+		}
+		ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list,
+					     flags, flag_count);
+	} else
+		ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list,
+					     NULL, 0);
 	if (!ret) {
 		/* Copy the new buffer offsets back to the user's exec list. */
 		ret = copy_to_user((struct drm_i915_relocation_entry __user *)
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index 692de60..76b37f6 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -657,6 +657,21 @@ struct drm_i915_gem_execbuffer2 {
 	__u64 rsvd2;
 };
 
+#define EXECBUFFER2_FLAGS_PTR(exec2) (exec2->rsvd1)
+#define EXECBUFFER2_FLAGS_COUNT(exec2)  ((uint32_t)(args->rsvd2>>32))
+#define EXECBUFFER2_CTX_ID(exec2) ((uint32_t)args->rsvd2 )
+
+struct drm_i915_context_flag {
+	__u8 slot;
+	__u32 handle;
+	__u64 offset;
+	__u32 read_domain;
+	__u32 write_domain;
+#define I915_CTX_ASSOC_BUF (1 << 0)
+#define I915_CTX_DISASSOC_BUF (1 << 1)
+	__u32 command;
+};
+
 struct drm_i915_gem_pin {
 	/** Handle of the buffer to be pinned. */
 	__u32 handle;
-- 
1.7.3.4




More information about the Intel-gfx mailing list