[Intel-gfx] [RFC 1/2] drm/i915: Offsets for golden context BB modification

Arun Siluvery arun.siluvery at linux.intel.com
Fri Jul 10 10:35:19 PDT 2015


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

Golden context batch buffers now contain a set of offsets
at which contents can optionally be modified.  This allows
the driver to customize the GC batch for various chipsets
in a GEN family.

v1 - Originally, the i915 driver was only allowed to
insert MI_BATCH_BUFFER_END commands at locations
specified by "alternate_bbend_offsets".

v2 - The previous "alternate_bbend_offsets" field has
been generalized in this version to allow the driver to
modify ranges of DWORDs in the golden context BB.  These
ranges are described in "mod_values" structs.

Signed-off-by:  Armin Reese <armin.c.reese at intel.com>
Signed-off-by: Arun Siluvery <arun.siluvery at linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_render_state.c  | 65 +++++++++++++++++++++++++--
 drivers/gpu/drm/i915/i915_gem_render_state.h  |  7 +++
 drivers/gpu/drm/i915/intel_renderstate.h      |  6 ++-
 drivers/gpu/drm/i915/intel_renderstate_gen6.c |  4 ++
 drivers/gpu/drm/i915/intel_renderstate_gen7.c |  4 ++
 drivers/gpu/drm/i915/intel_renderstate_gen8.c |  4 ++
 drivers/gpu/drm/i915/intel_renderstate_gen9.c |  4 ++
 7 files changed, 89 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c
index a0201fc..818233d 100644
--- a/drivers/gpu/drm/i915/i915_gem_render_state.c
+++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
@@ -45,6 +45,49 @@ render_state_get_rodata(struct drm_device *dev, const int gen)
 	return NULL;
 }
 
+/**
+ * Offsets for golden context "value modifications" defined in
+ * intel_renderstate_genx.c are locations in the batch buffer
+ * where the driver is allowed to modify one or more DWORDs
+ * to customize instructions for the GEN platform present.
+ */
+static int gc_modify_values(struct drm_device *dev,
+			 const struct intel_renderstate_rodata *rodata,
+			 u32 *d)
+{
+	/* Init index to "nothing to modify" value */
+	int mod_index = -1;
+	int mod_val[1];
+	int num_vals = 0;
+
+	/* Write required value(s) to the specified offset(s) */
+	if ((mod_index >= 0) &&
+	    (num_vals > 0)) {
+		if (mod_index < rodata->mod_value_items) {
+			int mod_offset, mod_max_cnt, i;
+
+			mod_offset =
+				rodata->mod_values[mod_index].offset;
+			mod_max_cnt =
+				rodata->mod_values[mod_index].max_cnt;
+
+			/* Check for DWORD aligned address, et al */
+			if ((num_vals > mod_max_cnt) ||
+			    (mod_offset <= 0) ||
+			    (mod_offset > PAGE_SIZE - (mod_max_cnt * sizeof(u32))) ||
+			    ((mod_offset & (sizeof(u32) - 1)) != 0))
+				return -EINVAL;
+
+			for (i = 0; i < num_vals; i++) {
+				d[(mod_offset/sizeof(u32)) + i] = mod_val[i];
+			}
+		} else
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int render_state_init(struct render_state *so, struct drm_device *dev)
 {
 	int ret;
@@ -73,7 +116,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 +132,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 +152,21 @@ static int render_state_setup(struct render_state *so)
 
 		d[i++] = s;
 	}
+
+	/* Any golden context BB entries to modify? */
+	if ((rodata->mod_values[0].offset != -1) &&
+	    (rodata->mod_values[0].max_cnt > 0))
+		ret = gc_modify_values(dev, rodata, d);
+	else
+		ret = 0;
+
 	kunmap(page);
 
+	if (ret) {
+		DRM_ERROR("error modifying golden context batch buffer contents\n");
+		return ret;
+	}
+
 	ret = i915_gem_object_set_to_gtt_domain(so->obj, false);
 	if (ret)
 		return ret;
@@ -143,7 +200,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 7aa7372..0898559 100644
--- a/drivers/gpu/drm/i915/i915_gem_render_state.h
+++ b/drivers/gpu/drm/i915/i915_gem_render_state.h
@@ -26,8 +26,15 @@
 
 #include <linux/types.h>
 
+struct mod_value_info {
+	u32 offset;
+	u32 max_cnt;
+};
+
 struct intel_renderstate_rodata {
 	const u32 *reloc;
+	const struct mod_value_info *mod_values;
+	const u32 mod_value_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..1a80279 100644
--- a/drivers/gpu/drm/i915/intel_renderstate.h
+++ b/drivers/gpu/drm/i915/intel_renderstate.h
@@ -34,8 +34,12 @@ extern const struct intel_renderstate_rodata gen9_null_state;
 #define RO_RENDERSTATE(_g)						\
 	const struct intel_renderstate_rodata gen ## _g ## _null_state = { \
 		.reloc = gen ## _g ## _null_state_relocs,		\
+		.mod_values = gen ## _g ## _mod_values,			\
+		.mod_value_items = (sizeof(gen ## _g ## _mod_values) /	\
+				    sizeof(struct mod_value_info)),	\
 		.batch = gen ## _g ## _null_state_batch,		\
-		.batch_items = sizeof(gen ## _g ## _null_state_batch)/4, \
+		.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 11c8e7b..ef29069 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen6.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen6.c
@@ -34,6 +34,10 @@ static const u32 gen6_null_state_relocs[] = {
 	-1,
 };
 
+static const struct mod_value_info gen6_mod_values[] = {
+	{-1, 0},
+};
+
 static const u32 gen6_null_state_batch[] = {
 	0x69040000,
 	0x790d0001,
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen7.c b/drivers/gpu/drm/i915/intel_renderstate_gen7.c
index 6551806..408e901 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen7.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen7.c
@@ -33,6 +33,10 @@ static const u32 gen7_null_state_relocs[] = {
 	-1,
 };
 
+static const struct mod_value_info gen7_mod_values[] = {
+	{-1, 0},
+};
+
 static const u32 gen7_null_state_batch[] = {
 	0x69040000,
 	0x61010008,
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen8.c b/drivers/gpu/drm/i915/intel_renderstate_gen8.c
index 95288a3..d5b1383 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen8.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen8.c
@@ -33,6 +33,10 @@ static const u32 gen8_null_state_relocs[] = {
 	-1,
 };
 
+static const struct mod_value_info gen8_mod_values[] = {
+	{-1, 0},
+};
+
 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 16a7ec2..7cb43a2 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen9.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen9.c
@@ -33,6 +33,10 @@ static const u32 gen9_null_state_relocs[] = {
 	-1,
 };
 
+static const struct mod_value_info gen9_mod_values[] = {
+	{-1, 0},
+};
+
 static const u32 gen9_null_state_batch[] = {
 	0x7a000004,
 	0x01000000,
-- 
1.9.1



More information about the Intel-gfx mailing list