[Intel-gfx] [PATCH 2/3] drm/i915: Alternate batch buffer end for golden context BB

armin.c.reese at intel.com armin.c.reese at intel.com
Fri Sep 12 20:25:15 CEST 2014


From: Armin Reese <armin.c.reese at intel.com>

Golden context batch buffers now can contain a set of offsets in
which to optionally place MI_BATCH_BUFFER_END commands.  This
allows the driver to customize the GC batch for various chipsets
in a family by requesting that the GC BB exit early for one chipset
to prevent execution of GPU commands intended for another chipset
in the same GEN family.

Signed-off-by: Armin Reese <armin.c.reese at intel.com>
---
 drivers/gpu/drm/i915/i915_gem_render_state.c  | 59 +++++++++++++++++++++++++--
 drivers/gpu/drm/i915/i915_gem_render_state.h  |  2 +
 drivers/gpu/drm/i915/intel_renderstate.h      | 14 +++++--
 drivers/gpu/drm/i915/intel_renderstate_gen6.c |  6 ++-
 drivers/gpu/drm/i915/intel_renderstate_gen7.c |  6 ++-
 drivers/gpu/drm/i915/intel_renderstate_gen8.c |  4 ++
 drivers/gpu/drm/i915/intel_renderstate_gen9.c | 29 +++++++++++--
 7 files changed, 106 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c
index 98dcd94..80aeff9 100644
--- a/drivers/gpu/drm/i915/i915_gem_render_state.c
+++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
@@ -45,6 +45,44 @@ render_state_get_rodata(struct drm_device *dev, const int gen)
 	return NULL;
 }
 
+/**
+ * Alternate batch buffer end offsets defined in intel_renderstate_genx.c
+ * are locations in the golden context batch buffer where MI_BATCH_BUFFER_END
+ * commands can be optionally inserted.  BB end commands can be added to
+ * terminate the GC BB early and thus customize the BB for product variations
+ * in a given GEN family.
+ */
+static int insert_alternate_bbend(struct drm_device *dev,
+				const struct intel_renderstate_rodata *rodata,
+				u32 *d)
+{
+	int index = -1;	/* Default to no alternate bbend index */
+
+	/* For GEN9, exit golden context BB before executing all commands */
+	if (IS_GEN9(dev))
+		index = 0;
+
+	/* Write MI_BATCH_BUFFER_END at valid location */
+	if (index >= 0) {
+		if (index < rodata->alternate_bbend_items) {
+			int bbend_offset;
+
+			bbend_offset = rodata->alternate_bbend_offsets[index];
+
+			/* Check for DWORD aligned address, et al */
+			if ((bbend_offset <= 0) ||
+			    (bbend_offset > PAGE_SIZE - sizeof(u32)) ||
+			    ((bbend_offset & (sizeof(u32) - 1)) != 0))
+				return -EINVAL;
+
+			d[bbend_offset/sizeof(u32)] = MI_BATCH_BUFFER_END;
+		} else
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int render_state_init(struct render_state *so, struct drm_device *dev)
 {
 	int ret;
@@ -73,7 +111,7 @@ free_gem:
 	return ret;
 }
 
-static int render_state_setup(struct render_state *so)
+static int render_state_setup(struct render_state *so, struct drm_device *dev)
 {
 	const struct intel_renderstate_rodata *rodata = so->rodata;
 	unsigned int i = 0, reloc_index = 0;
@@ -89,10 +127,11 @@ static int render_state_setup(struct render_state *so)
 	d = kmap(page);
 
 	while (i < rodata->batch_items) {
-		u32 s = rodata->batch[i];
+		u32 s = rodata->batch[i];	/* DWORD from R/O batch */
 
 		if (i * 4  == rodata->reloc[reloc_index]) {
-			u64 r = s + so->ggtt_offset;
+			u64 r = s + /* Object offset stored in reloc DWORD */
+				so->ggtt_offset; /* Batch buffer gfx offset */
 			s = lower_32_bits(r);
 			if (so->gen >= 8) {
 				if (i + 1 >= rodata->batch_items ||
@@ -108,8 +147,20 @@ static int render_state_setup(struct render_state *so)
 
 		d[i++] = s;
 	}
+
+	/* Any alternate BB end entries? */
+	if (rodata->alternate_bbend_offsets[0] != -1)
+		ret = insert_alternate_bbend(dev, rodata, d);
+	else
+		ret = 0;
+
 	kunmap(page);
 
+	if (ret) {
+		DRM_ERROR("invalid alternate batch buffer end\n");
+		return ret;
+	}
+
 	ret = i915_gem_object_set_to_gtt_domain(so->obj, false);
 	if (ret)
 		return ret;
@@ -143,7 +194,7 @@ int i915_gem_render_state_prepare(struct intel_engine_cs *ring,
 	if (so->rodata == NULL)
 		return 0;
 
-	ret = render_state_setup(so);
+	ret = render_state_setup(so, ring->dev);
 	if (ret) {
 		i915_gem_render_state_fini(so);
 		return ret;
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.h b/drivers/gpu/drm/i915/i915_gem_render_state.h
index c44961e..3f540c8 100644
--- a/drivers/gpu/drm/i915/i915_gem_render_state.h
+++ b/drivers/gpu/drm/i915/i915_gem_render_state.h
@@ -28,6 +28,8 @@
 
 struct intel_renderstate_rodata {
 	const u32 *reloc;
+	const u32 *alternate_bbend_offsets;
+	const u32 alternate_bbend_items;
 	const u32 *batch;
 	const u32 batch_items;
 };
diff --git a/drivers/gpu/drm/i915/intel_renderstate.h b/drivers/gpu/drm/i915/intel_renderstate.h
index 5bd6985..8d5d975 100644
--- a/drivers/gpu/drm/i915/intel_renderstate.h
+++ b/drivers/gpu/drm/i915/intel_renderstate.h
@@ -31,11 +31,17 @@ extern const struct intel_renderstate_rodata gen7_null_state;
 extern const struct intel_renderstate_rodata gen8_null_state;
 extern const struct intel_renderstate_rodata gen9_null_state;
 
-#define RO_RENDERSTATE(_g)						\
+#define RO_RENDERSTATE(_g) \
 	const struct intel_renderstate_rodata gen ## _g ## _null_state = { \
-		.reloc = gen ## _g ## _null_state_relocs,		\
-		.batch = gen ## _g ## _null_state_batch,		\
-		.batch_items = sizeof(gen ## _g ## _null_state_batch)/4, \
+		.reloc = gen ## _g ## _null_state_relocs, \
+		.alternate_bbend_offsets = \
+			gen ## _g ## _alternate_bbend_offsets, \
+		.alternate_bbend_items = \
+			sizeof(gen ## _g ## _alternate_bbend_offsets) / \
+			sizeof(u32), \
+		.batch = gen ## _g ## _null_state_batch, \
+		.batch_items = sizeof(gen ## _g ## _null_state_batch) / \
+				sizeof(u32) \
 	}
 
 #endif /* INTEL_RENDERSTATE_H */
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen6.c b/drivers/gpu/drm/i915/intel_renderstate_gen6.c
index c2568a7..95e30f8 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen6.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen6.c
@@ -29,7 +29,11 @@ static const u32 gen6_null_state_relocs[] = {
 	0x0000002c,
 	0x000001e0,
 	0x000001e4,
-	-1,
+	-1
+};
+
+static const u32 gen6_alternate_bbend_offsets[] = {
+	-1
 };
 
 static const u32 gen6_null_state_batch[] = {
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen7.c b/drivers/gpu/drm/i915/intel_renderstate_gen7.c
index e14aec5..c22b89f 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen7.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen7.c
@@ -28,7 +28,11 @@ static const u32 gen7_null_state_relocs[] = {
 	0x00000010,
 	0x00000018,
 	0x000001ec,
-	-1,
+	-1
+};
+
+static const u32 gen7_alternate_bbend_offsets[] = {
+	-1
 };
 
 static const u32 gen7_null_state_batch[] = {
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen8.c b/drivers/gpu/drm/i915/intel_renderstate_gen8.c
index 88991e2..282012e 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen8.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen8.c
@@ -31,6 +31,10 @@ static const u32 gen8_null_state_relocs[] = {
 	-1,
 };
 
+static const u32 gen8_alternate_bbend_offsets[] = {
+	-1
+};
+
 static const u32 gen8_null_state_batch[] = {
 	0x7a000004,
 	0x01000000,
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen9.c b/drivers/gpu/drm/i915/intel_renderstate_gen9.c
index e1ea838..eca1384 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen9.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen9.c
@@ -31,6 +31,11 @@ static const u32 gen9_null_state_relocs[] = {
 	-1,
 };
 
+static const u32 gen9_alternate_bbend_offsets[] = {
+	0x00000dac,
+	-1
+};
+
 static const u32 gen9_null_state_batch[] = {
 	0x7a000004,
 	0x01000000,
@@ -867,9 +872,9 @@ static const u32 gen9_null_state_batch[] = {
 	0x00000000,
 	0x680b0001,
 	0x780e0000,
-	0x00000dc1,
-	0x78240000,
 	0x00000e01,
+	0x78240000,
+	0x00000e41,
 	0x784f0000,
 	0x80000100,
 	0x784d0000,
@@ -887,9 +892,9 @@ static const u32 gen9_null_state_batch[] = {
 	0x780f0000,
 	0x00000000,
 	0x78230000,
-	0x00000e60,
+	0x00000ea0,
 	0x78210000,
-	0x00000e80,
+	0x00000ec0,
 	0x78260000,
 	0x00000000,
 	0x78270000,
@@ -907,11 +912,27 @@ static const u32 gen9_null_state_batch[] = {
 	0x00000001,
 	0x00000000,
 	0x00000000,
+	0x00000000,	 /* alternate bbend */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
 	0x05000000,	 /* cmds end */
 	0x00000000,
 	0x00000000,
 	0x00000000,
 	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
 	0x00000000,	 /* state start */
 	0x00000000,
 	0x3f800000,
-- 
1.9.1




More information about the Intel-gfx mailing list