[PATCH 46/66] drm/i915: Permit contexts on all rings

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If we want to use contexts in more abstract terms (specifically with
PPGTT in mind), we need to allow them to be specified for any ring.

NOTE: This commit requires an update to intel-gpu-tools to make it not
fail.

Signed-off-by: Ben Widawsky <ben at bwidawsk.net>
---
 drivers/gpu/drm/i915/i915_gem_context.c    | 56 ++++++++++++++++++++++--------
 drivers/gpu/drm/i915/i915_gem_execbuffer.c | 16 ---------
 2 files changed, 42 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index a5ac6dd..74714e56 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -97,7 +97,8 @@
 
 static struct i915_hw_context *
 i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id);
-static int do_switch(struct i915_hw_context *to);
+static int do_switch(struct intel_ring_buffer *ring,
+		     struct i915_hw_context *to);
 
 static int get_context_size(struct drm_device *dev)
 {
@@ -204,13 +205,19 @@ static inline bool is_default_context(struct i915_hw_context *ctx)
  * context state of the GPU for applications that don't utilize HW contexts, as
  * well as an idle case.
  */
-static int create_default_context(struct drm_i915_private *dev_priv)
+static int create_default_context(struct drm_i915_private *dev_priv,
+				  struct intel_ring_buffer *ring)
 {
 	struct i915_hw_context *ctx;
 	int ret;
 
 	BUG_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
 
+	if (dev_priv->ring[RCS].default_context) {
+		ring->default_context = dev_priv->ring[RCS].default_context;
+		return 0;
+	}
+
 	ctx = create_hw_context(dev_priv->dev, NULL);
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
@@ -241,6 +248,8 @@ err_destroy:
 void i915_gem_context_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_ring_buffer *ring;
+	int i;
 
 	if (!HAS_HW_CONTEXTS(dev)) {
 		dev_priv->hw_contexts_disabled = true;
@@ -262,10 +271,17 @@ void i915_gem_context_init(struct drm_device *dev)
 		return;
 	}
 
-	if (create_default_context(dev_priv)) {
-		dev_priv->hw_contexts_disabled = true;
-		DRM_DEBUG_DRIVER("Disabling HW Contexts; create failed\n");
-		return;
+
+	for (i = 0; i < I915_NUM_RINGS; i++) {
+		if (!(INTEL_INFO(dev)->ring_mask & (1<<i)))
+			continue;
+
+		ring = &dev_priv->ring[i];
+		if (create_default_context(dev_priv, ring)) {
+			dev_priv->hw_contexts_disabled = true;
+			DRM_DEBUG_DRIVER("Disabling HW Contexts; create failed\n");
+			return;
+		}
 	}
 
 	DRM_DEBUG_DRIVER("HW context support initialized\n");
@@ -310,7 +326,8 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv)
 	if (dev_priv->hw_contexts_disabled)
 		return 0;
 	BUG_ON(!dev_priv->ring[RCS].default_context);
-	return do_switch(dev_priv->ring[RCS].default_context);
+	return do_switch(&dev_priv->ring[RCS],
+			 dev_priv->ring[RCS].default_context);
 }
 
 static int context_idr_cleanup(int id, void *p, void *data)
@@ -437,19 +454,32 @@ mi_set_context(struct intel_ring_buffer *ring,
 	return ret;
 }
 
-static int do_switch(struct i915_hw_context *to)
+static int do_switch(struct intel_ring_buffer *ring,
+		     struct i915_hw_context *to)
 {
-	struct intel_ring_buffer *ring = to->ring;
 	struct drm_i915_private *dev_priv = ring->dev->dev_private;
 	struct i915_hw_context *from = ring->last_context;
 	u32 hw_flags = 0;
 	int ret;
 
-	BUG_ON(from != NULL && from->obj != NULL && from->obj->pin_count == 0);
+	if (from != NULL && ring == &dev_priv->ring[RCS]) {
+		BUG_ON(from->obj == NULL);
+		BUG_ON(from->obj->pin_count == 0);
+	}
 
 	if (from == to)
 		return 0;
 
+	if (ring != &dev_priv->ring[RCS] && from) {
+		ret = i915_add_request(ring, NULL);
+		if (ret)
+			return ret;
+		i915_gem_context_unreference(from);
+	}
+
+	if (ring != &dev_priv->ring[RCS])
+		goto done;
+
 	ret = i915_gem_ggtt_pin(to->obj, CONTEXT_ALIGN, false, false);
 	if (ret)
 		return ret;
@@ -514,6 +544,7 @@ static int do_switch(struct i915_hw_context *to)
 		i915_gem_context_unreference(from);
 	}
 
+done:
 	i915_gem_context_reference(to);
 	ring->last_context = to;
 	to->is_initialized = true;
@@ -546,9 +577,6 @@ int i915_switch_context(struct intel_ring_buffer *ring,
 
 	WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
 
-	if (ring != &dev_priv->ring[RCS])
-		return 0;
-
 	if (to_id == DEFAULT_CONTEXT_ID) {
 		to = ring->default_context;
 	} else {
@@ -560,7 +588,7 @@ int i915_switch_context(struct intel_ring_buffer *ring,
 			return -ENOENT;
 	}
 
-	return do_switch(to);
+	return do_switch(ring, to);
 }
 
 int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 7e9823f..b3e3658 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -892,29 +892,13 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 		break;
 	case I915_EXEC_BSD:
 		ring = &dev_priv->ring[VCS];
-		if (ctx_id != 0) {
-			DRM_DEBUG("Ring %s doesn't support contexts\n",
-				  ring->name);
-			return -EPERM;
-		}
 		break;
 	case I915_EXEC_BLT:
 		ring = &dev_priv->ring[BCS];
-		if (ctx_id != 0) {
-			DRM_DEBUG("Ring %s doesn't support contexts\n",
-				  ring->name);
-			return -EPERM;
-		}
 		break;
 	case I915_EXEC_VEBOX:
 		ring = &dev_priv->ring[VECS];
-		if (ctx_id != 0) {
-			DRM_DEBUG("Ring %s doesn't support contexts\n",
-				  ring->name);
-			return -EPERM;
-		}
 		break;
-
 	default:
 		DRM_DEBUG("execbuf with unknown ring: %d\n",
 			  (int)(args->flags & I915_EXEC_RING_MASK));
-- 
1.8.3.1



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux