From: Armin Reese <[email protected]>

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 <[email protected]>
Signed-off-by: Arun Siluvery <[email protected]>
---
 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

_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to