From: Armin Reese <armin.c.reese@xxxxxxxxx> 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@xxxxxxxxx> --- 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 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx