summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2017-09-25 22:06:12 +0300
committerChris Wilson <chris@chris-wilson.co.uk>2017-10-18 16:07:47 +0100
commit4798e18b2b2c8b0a05dc967e6140fd9962bc1a73 (patch)
tree45295fb51c1187dd034e062a9c884b8811139f8b
parent04b4f3b7f7b3aa5837854fa2613b3473d7fed7cd (diff)
sna: Implement i830 3DSTATE_BUFFER_INFO w/a
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ä <ville.syrjala@linux.intel.com>
-rw-r--r--src/sna/gen2_render.c13
-rw-r--r--src/sna/sna_render_inline.h9
2 files changed, 20 insertions, 2 deletions
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);