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 <b...@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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to