[Intel-gfx] [PATCH 50/53] drm/i915/bdw: Render state init for Execlists

oscar.mateo at intel.com oscar.mateo at intel.com
Fri Jun 13 17:38:08 CEST 2014


From: Oscar Mateo <oscar.mateo at intel.com>

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.

Signed-off-by: Oscar Mateo <oscar.mateo at intel.com>
---
 drivers/gpu/drm/i915/i915_gem_context.c      | 17 ++++++++++-
 drivers/gpu/drm/i915/i915_gem_render_state.c | 20 ++++---------
 drivers/gpu/drm/i915/intel_lrc.c             | 43 ++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_lrc.h             |  2 ++
 drivers/gpu/drm/i915/intel_renderstate.h     | 13 +++++++++
 5 files changed, 80 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 99bdd5e..2350e8c 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -512,8 +512,23 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv)
 		ppgtt->enable(ppgtt);
 	}
 
-	if (dev_priv->lrc_enabled)
+	if (dev_priv->lrc_enabled) {
+		struct intel_context *dctx;
+
+		ring = &dev_priv->ring[RCS];
+		dctx = ring->default_context;
+
+		if (!dctx->is_initialized) {
+			ret = intel_lr_context_render_state_init(ring, dctx);
+			if (ret) {
+				DRM_ERROR("Init render state failed: %d\n", ret);
+				return ret;
+			}
+			dctx->is_initialized = true;
+		}
+
 		return 0;
+	}
 
 	/* FIXME: We should make this work, even in reset */
 	if (i915_reset_in_progress(&dev_priv->gpu_error))
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c
index 5944c0a..08d8275 100644
--- a/drivers/gpu/drm/i915/i915_gem_render_state.c
+++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
@@ -28,14 +28,6 @@
 #include "i915_drv.h"
 #include "intel_renderstate.h"
 
-struct i915_render_state {
-	struct drm_i915_gem_object *obj;
-	unsigned long ggtt_offset;
-	void *batch;
-	u32 size;
-	u32 len;
-};
-
 static struct i915_render_state *render_state_alloc(struct drm_device *dev)
 {
 	struct i915_render_state *so;
@@ -78,7 +70,7 @@ free:
 	return ERR_PTR(ret);
 }
 
-static void render_state_free(struct i915_render_state *so)
+void i915_gem_render_state_free(struct i915_render_state *so)
 {
 	kunmap(so->batch);
 	i915_gem_object_ggtt_unpin(so->obj);
@@ -159,8 +151,8 @@ static int render_state_setup(const int gen,
 	return 0;
 }
 
-static struct i915_render_state *
-render_state_prepare(struct intel_engine_cs *ring)
+struct i915_render_state *
+i915_gem_render_state_prepare(struct intel_engine_cs *ring)
 {
 	const int gen = INTEL_INFO(ring->dev)->gen;
 	struct i915_render_state *so;
@@ -180,7 +172,7 @@ render_state_prepare(struct intel_engine_cs *ring)
 
 	ret = render_state_setup(gen, rodata, so);
 	if (ret) {
-		render_state_free(so);
+		i915_gem_render_state_free(so);
 		return ERR_PTR(ret);
 	}
 
@@ -192,7 +184,7 @@ int i915_gem_render_state_init(struct intel_engine_cs *ring)
 	struct i915_render_state *so;
 	int ret;
 
-	so = render_state_prepare(ring);
+	so = i915_gem_render_state_prepare(ring);
 	if (IS_ERR_OR_NULL(so))
 		return PTR_ERR(so);
 
@@ -208,6 +200,6 @@ int i915_gem_render_state_init(struct intel_engine_cs *ring)
 	ret = __i915_add_request(ring, NULL, so->obj, NULL);
 	/* __i915_add_request moves object to inactive if it fails */
 out:
-	render_state_free(so);
+	i915_gem_render_state_free(so);
 	return ret;
 }
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index c23c0f6..45f5485 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -40,6 +40,7 @@
 #include <drm/drmP.h>
 #include <drm/i915_drm.h>
 #include "i915_drv.h"
+#include "intel_renderstate.h"
 
 #define GEN8_LR_CONTEXT_RENDER_SIZE (20 * PAGE_SIZE)
 #define GEN8_LR_CONTEXT_OTHER_SIZE (2 * PAGE_SIZE)
@@ -1406,6 +1407,33 @@ cleanup_render_ring:
 	return ret;
 }
 
+int intel_lr_context_render_state_init(struct intel_engine_cs *ring,
+				       struct intel_context *ctx)
+{
+	struct i915_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;
+
+	so = i915_gem_render_state_prepare(ring);
+	if (IS_ERR_OR_NULL(so))
+		return PTR_ERR(so);
+
+	ret = ring->emit_bb_start(ring, ctx,
+			i915_gem_obj_ggtt_offset(so->obj),
+			I915_DISPATCH_SECURE);
+	if (ret)
+		goto out;
+
+	i915_vma_move_to_active(i915_gem_obj_to_ggtt(so->obj), ring);
+
+	ret = intel_logical_ring_add_request(ring, file, so->obj, NULL);
+	/* intel_logical_ring_add_request moves object to inactive if it fails */
+out:
+	i915_gem_render_state_free(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 drm_i915_gem_object *ring_obj)
@@ -1616,6 +1644,21 @@ int intel_lr_context_deferred_create(struct intel_context *ctx,
 	ctx->engine[ring->id].ringbuf = ringbuf;
 	ctx->engine[ring->id].obj = ctx_obj;
 
+	/* The default context will have to wait, because we are not yet
+	 * ready to send a batchbuffer at this point */
+	if (ring->id == RCS && !ctx->is_initialized &&
+			ctx != ring->default_context) {
+		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].obj = NULL;
+			intel_destroy_ring_buffer(ringbuf);
+			goto error;
+		}
+		ctx->is_initialized = true;
+	}
+
 	return 0;
 
 error:
diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
index c318dcb..34b1189 100644
--- a/drivers/gpu/drm/i915/intel_lrc.h
+++ b/drivers/gpu/drm/i915/intel_lrc.h
@@ -43,6 +43,8 @@ int intel_logical_ring_begin(struct intel_engine_cs *ring,
 			     int num_dwords);
 
 /* Logical Ring Contexts */
+int intel_lr_context_render_state_init(struct intel_engine_cs *ring,
+				       struct intel_context *ctx);
 void intel_lr_context_free(struct intel_context *ctx);
 int intel_lr_context_deferred_create(struct intel_context *ctx,
 				     struct intel_engine_cs *ring);
diff --git a/drivers/gpu/drm/i915/intel_renderstate.h b/drivers/gpu/drm/i915/intel_renderstate.h
index a5e783a..65a4740 100644
--- a/drivers/gpu/drm/i915/intel_renderstate.h
+++ b/drivers/gpu/drm/i915/intel_renderstate.h
@@ -25,6 +25,15 @@
 #define _INTEL_RENDERSTATE_H
 
 #include <linux/types.h>
+#include "i915_drv.h"
+
+struct i915_render_state {
+	struct drm_i915_gem_object *obj;
+	unsigned long ggtt_offset;
+	void *batch;
+	u32 size;
+	u32 len;
+};
 
 struct intel_renderstate_rodata {
 	const u32 *reloc;
@@ -45,4 +54,8 @@ extern const struct intel_renderstate_rodata gen8_null_state;
 		.batch_items = sizeof(gen ## _g ## _null_state_batch)/4, \
 	}
 
+void i915_gem_render_state_free(struct i915_render_state *so);
+struct i915_render_state *
+i915_gem_render_state_prepare(struct intel_engine_cs *ring);
+
 #endif /* INTEL_RENDERSTATE_H */
-- 
1.9.0




More information about the Intel-gfx mailing list