aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_lrc.c
diff options
context:
space:
mode:
authorOscar Mateo <oscar.mateo@intel.com>2014-08-21 11:40:54 +0100
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-09-03 11:04:52 +0200
commit564ddb2fae4da01406a24e5a763e601dc21c23d7 (patch)
tree48b36deb20a0ac13323ca2d6c99235bddac0b0a2 /drivers/gpu/drm/i915/intel_lrc.c
parentdrm/i915/bdw: BDW Software Turbo (diff)
downloadlinux-dev-564ddb2fae4da01406a24e5a763e601dc21c23d7.tar.xz
linux-dev-564ddb2fae4da01406a24e5a763e601dc21c23d7.zip
drm/i915/bdw: Render state init for Execlists
The batchbuffer that sets the render context state is submitted in a different way, and from different places. We needed to make both the render state preparation and free functions outside accesible, and namespace accordingly. This mess is so that all LR, LRC and Execlists functionality can go together in intel_lrc.c: we can fix all of this later on, once the interfaces are clear. v2: Create a separate ctx->rcs_initialized for the Execlists case, as suggested by Chris Wilson. Signed-off-by: Oscar Mateo <oscar.mateo@intel.com> v3: Setup ring status page in lr_context_deferred_create when the default context is being created. This means that the render state init for the default context is no longer a special case. Execute deferred creation of the default context at the end of logical_ring_init to allow the render state commands to be submitted. Fix style errors reported by checkpatch. Rebased. Signed-off-by: Thomas Daniel <thomas.daniel@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_lrc.c')
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c73
1 files changed, 58 insertions, 15 deletions
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index b54f31207cac..bd1b28d99920 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1217,8 +1217,6 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *ring)
static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *ring)
{
int ret;
- struct intel_context *dctx = ring->default_context;
- struct drm_i915_gem_object *dctx_obj;
/* Intentionally left blank. */
ring->buffer = NULL;
@@ -1232,18 +1230,6 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin
spin_lock_init(&ring->execlist_lock);
ring->next_context_status_buffer = 0;
- ret = intel_lr_context_deferred_create(dctx, ring);
- if (ret)
- return ret;
-
- /* The status page is offset 0 from the context object in LRCs. */
- dctx_obj = dctx->engine[ring->id].state;
- ring->status_page.gfx_addr = i915_gem_obj_ggtt_offset(dctx_obj);
- ring->status_page.page_addr = kmap(sg_page(dctx_obj->pages->sgl));
- if (ring->status_page.page_addr == NULL)
- return -ENOMEM;
- ring->status_page.obj = dctx_obj;
-
ret = i915_cmd_parser_init_ring(ring);
if (ret)
return ret;
@@ -1254,7 +1240,9 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin
return ret;
}
- return 0;
+ ret = intel_lr_context_deferred_create(ring->default_context, ring);
+
+ return ret;
}
static int logical_render_ring_init(struct drm_device *dev)
@@ -1448,6 +1436,38 @@ cleanup_render_ring:
return ret;
}
+int intel_lr_context_render_state_init(struct intel_engine_cs *ring,
+ struct intel_context *ctx)
+{
+ struct intel_ringbuffer *ringbuf = ctx->engine[ring->id].ringbuf;
+ struct render_state so;
+ struct drm_i915_file_private *file_priv = ctx->file_priv;
+ struct drm_file *file = file_priv ? file_priv->file : NULL;
+ int ret;
+
+ ret = i915_gem_render_state_prepare(ring, &so);
+ if (ret)
+ return ret;
+
+ if (so.rodata == NULL)
+ return 0;
+
+ ret = ring->emit_bb_start(ringbuf,
+ so.ggtt_offset,
+ I915_DISPATCH_SECURE);
+ if (ret)
+ goto out;
+
+ i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), ring);
+
+ ret = __i915_add_request(ring, file, so.obj, NULL);
+ /* intel_logical_ring_add_request moves object to inactive if it
+ * fails */
+out:
+ i915_gem_render_state_fini(&so);
+ return ret;
+}
+
static int
populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_obj,
struct intel_engine_cs *ring, struct intel_ringbuffer *ringbuf)
@@ -1692,6 +1712,29 @@ int intel_lr_context_deferred_create(struct intel_context *ctx,
ctx->engine[ring->id].ringbuf = ringbuf;
ctx->engine[ring->id].state = ctx_obj;
+ if (ctx == ring->default_context) {
+ /* The status page is offset 0 from the default context object
+ * in LRC mode. */
+ ring->status_page.gfx_addr = i915_gem_obj_ggtt_offset(ctx_obj);
+ ring->status_page.page_addr =
+ kmap(sg_page(ctx_obj->pages->sgl));
+ if (ring->status_page.page_addr == NULL)
+ return -ENOMEM;
+ ring->status_page.obj = ctx_obj;
+ }
+
+ if (ring->id == RCS && !ctx->rcs_initialized) {
+ ret = intel_lr_context_render_state_init(ring, ctx);
+ if (ret) {
+ DRM_ERROR("Init render state failed: %d\n", ret);
+ ctx->engine[ring->id].ringbuf = NULL;
+ ctx->engine[ring->id].state = NULL;
+ intel_destroy_ringbuffer_obj(ringbuf);
+ goto error;
+ }
+ ctx->rcs_initialized = true;
+ }
+
return 0;
error: