Again for the sake of review, this commit is broken out. Context init
for default context and subsequent contexts is implemented here. Since
none of the context_switch code is implemented, it doesn't really do
much.
---
 drivers/gpu/drm/i915/i915_context.c |   67 +++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/i915_drv.h     |    5 +++
 2 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_context.c 
b/drivers/gpu/drm/i915/i915_context.c
index 45b5181..2e38fa8 100644
--- a/drivers/gpu/drm/i915/i915_context.c
+++ b/drivers/gpu/drm/i915/i915_context.c
@@ -99,13 +99,70 @@ static int context_init(struct drm_i915_gem_context *ctx,
                        bool wait_for_switch)
 {
        struct drm_i915_private *dev_priv = ctx->dev->dev_private;
-       struct drm_i915_gem_context *last;
+       struct drm_i915_gem_context *last = NULL;
        int ret;
 
        if (ring->context_switch == NULL)
                return 0;
 
-       return -ENOMEM;
+       drm_gem_object_reference(&ctx->obj->base);
+       ret = i915_gem_object_pin(ctx->obj, CONTEXT_ALIGN, false);
+       if (ret) {
+               drm_gem_object_unreference(&ctx->obj->base);
+               return ret;
+       }
+
+       if (ctx->is_default) {
+               /*
+                * XXX default context is always first. The first context needs
+                * to do an extra save because the first save (according to the
+                * spec) doesn't actually do anything. So the outcome is
+                * 1. Save without restore (no context saved)
+                * 2. Save without restore (context is saved)
+                * 3. Save with restore (loads the ctx from step 2)
+                */
+               last = ring->context_switch(ring, ctx, 0,
+                                           I915_CONTEXT_SAVE_ONLY);
+               if (!last) {
+                       ret = EIO;
+                       goto err_out;
+               }
+               last = ring->context_switch(ring, ctx, 0,
+                                           I915_CONTEXT_SAVE_ONLY |
+                                           I915_CONTEXT_FORCED_SWITCH);
+               if (!last) {
+                       ret = EIO;
+                       goto err_out;
+               }
+               last = ring->context_switch(ring, ctx, 0,
+                                           I915_CONTEXT_NORMAL_SWITCH |
+                                           I915_CONTEXT_FORCED_SWITCH);
+       } else {
+               last = ring->context_switch(ring, ctx, 0,
+                                           I915_CONTEXT_SAVE_ONLY);
+       }
+
+       if (!last) {
+               ret = EIO;
+               goto err_out;
+       }
+
+       if (!last->is_default)
+               i915_release_context(last);
+
+       if (wait_for_switch) {
+               ret = wait_for_context_switch(ring);
+               if (ret)
+                       goto err_out;
+       }
+
+       return 0;
+
+err_out:
+       WARN_ON(ctx->is_default);
+       i915_gem_object_unpin(ctx->obj);
+       drm_gem_object_unreference(&ctx->obj->base);
+       return ret;
 }
 
 /*
@@ -316,3 +373,9 @@ struct drm_i915_gem_context *i915_get_context(struct 
drm_file *file,
 {
        return NULL;
 }
+
+void i915_release_context(struct drm_i915_gem_context *ctx)
+{
+       i915_gem_object_unpin(ctx->obj);
+       drm_gem_object_unreference(&ctx->obj->base);
+}
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 15f86fb..98ccbd9 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -914,6 +914,10 @@ struct drm_i915_gem_context {
        int slot_count;
 };
 
+#define I915_CONTEXT_NORMAL_SWITCH     (1 << 0)
+#define I915_CONTEXT_SAVE_ONLY         (1 << 1)
+#define I915_CONTEXT_FORCED_SWITCH     (1 << 2)
+
 enum intel_chip_family {
        CHIP_I8XX = 0x01,
        CHIP_I9XX = 0x02,
@@ -1157,6 +1161,7 @@ extern void i915_context_open(struct drm_device *dev, 
struct drm_file *file);
 extern void i915_context_close(struct drm_device *dev, struct drm_file *file);
 extern struct drm_i915_gem_context *i915_get_context(struct drm_file *file,
                                                     uint32_t id);
+extern void i915_release_context(struct drm_i915_gem_context *ctx);
 
 /**
  * Returns true if seq1 is later than seq2.
-- 
1.7.3.4

_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to