From 4798e18b2b2c8b0a05dc967e6140fd9962bc1a73 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 25 Sep 2017 22:06:12 +0300 Subject: sna: Implement i830 3DSTATE_BUFFER_INFO w/a MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit i830 can hang if 3DSTATE_BUFFER_INFO straddles two cachelines. To prevent that emit MI_NOOPs to align 3DSTATE_BUFFER_INFO to a cacheline boundary. Signed-off-by: Ville Syrjälä --- src/sna/gen2_render.c | 13 +++++++++++-- src/sna/sna_render_inline.h | 9 +++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c index 49ad16a3..e03c4401 100644 --- a/src/sna/gen2_render.c +++ b/src/sna/gen2_render.c @@ -52,6 +52,7 @@ #define MAX_INLINE (1 << 18) #define BATCH(v) batch_emit(sna, v) +#define BATCH_ALIGNED(v, a) batch_emit_aligned(sna, v, a) #define BATCH_F(v) batch_emit_float(sna, v) #define VERTEX(v) batch_emit_float(sna, v) @@ -568,7 +569,8 @@ gen2_get_batch(struct sna *sna, const struct sna_composite_op *op) { kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo); - if (!kgem_check_batch(&sna->kgem, INVARIANT_SIZE+40)) { + /* +7 for i830 3DSTATE_BUFFER_INFO w/a */ + if (!kgem_check_batch(&sna->kgem, INVARIANT_SIZE+40+7)) { DBG(("%s: flushing batch: size %d > %d\n", __FUNCTION__, INVARIANT_SIZE+40, sna->kgem.surface-sna->kgem.nbatch)); @@ -614,7 +616,14 @@ static void gen2_emit_target(struct sna *sna, return; } - BATCH(_3DSTATE_BUF_INFO_CMD); + /* + * i830 w/a: 3DSTATE_BUFFER_INFO + * must not straddle two cachelines. + */ + if (intel_get_device_id(sna->dev) == 0x3577) + BATCH_ALIGNED(_3DSTATE_BUF_INFO_CMD, 8); + else + BATCH(_3DSTATE_BUF_INFO_CMD); BATCH(BUF_3D_ID_COLOR_BACK | gen2_buf_tiling(bo->tiling) | BUF_3D_PITCH(bo->pitch)); diff --git a/src/sna/sna_render_inline.h b/src/sna/sna_render_inline.h index e162e37f..f2d9c226 100644 --- a/src/sna/sna_render_inline.h +++ b/src/sna/sna_render_inline.h @@ -56,6 +56,15 @@ static force_inline void batch_emit(struct sna *sna, uint32_t dword) sna->kgem.batch[sna->kgem.nbatch++] = dword; } +static force_inline void batch_emit_aligned(struct sna *sna, uint32_t dword, unsigned align) +{ + assert(sna->kgem.mode != KGEM_NONE); + assert(sna->kgem.nbatch + KGEM_BATCH_RESERVED < sna->kgem.surface); + while (sna->kgem.nbatch & (align-1)) + sna->kgem.batch[sna->kgem.nbatch++] = 0; + sna->kgem.batch[sna->kgem.nbatch++] = dword; +} + static force_inline void batch_emit64(struct sna *sna, uint64_t qword) { assert(sna->kgem.mode != KGEM_NONE); -- cgit v1.2.3