diff mbox

[4/8] drm/i915/context: minimal support for contexts in execbuffer2

Message ID 1296687620-27019-5-git-send-email-bwidawsk@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ben Widawsky Feb. 2, 2011, 11 p.m. UTC
None
diff mbox

Patch

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;