[Intel-gfx] [PATCH 46/66] drm/i915: Permit contexts on all rings
Ben Widawsky
ben at bwidawsk.net
Fri Jun 28 01:30:47 CEST 2013
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
More information about the Intel-gfx
mailing list