|
@@ -91,6 +91,7 @@ static int
|
|
gen4_render_ring_flush(struct i915_request *rq, u32 mode)
|
|
gen4_render_ring_flush(struct i915_request *rq, u32 mode)
|
|
{
|
|
{
|
|
u32 cmd, *cs;
|
|
u32 cmd, *cs;
|
|
|
|
+ int i;
|
|
|
|
|
|
/*
|
|
/*
|
|
* read/write caches:
|
|
* read/write caches:
|
|
@@ -127,12 +128,45 @@ gen4_render_ring_flush(struct i915_request *rq, u32 mode)
|
|
cmd |= MI_INVALIDATE_ISP;
|
|
cmd |= MI_INVALIDATE_ISP;
|
|
}
|
|
}
|
|
|
|
|
|
- cs = intel_ring_begin(rq, 2);
|
|
|
|
|
|
+ i = 2;
|
|
|
|
+ if (mode & EMIT_INVALIDATE)
|
|
|
|
+ i += 20;
|
|
|
|
+
|
|
|
|
+ cs = intel_ring_begin(rq, i);
|
|
if (IS_ERR(cs))
|
|
if (IS_ERR(cs))
|
|
return PTR_ERR(cs);
|
|
return PTR_ERR(cs);
|
|
|
|
|
|
*cs++ = cmd;
|
|
*cs++ = cmd;
|
|
- *cs++ = MI_NOOP;
|
|
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * A random delay to let the CS invalidate take effect? Without this
|
|
|
|
+ * delay, the GPU relocation path fails as the CS does not see
|
|
|
|
+ * the updated contents. Just as important, if we apply the flushes
|
|
|
|
+ * to the EMIT_FLUSH branch (i.e. immediately after the relocation
|
|
|
|
+ * write and before the invalidate on the next batch), the relocations
|
|
|
|
+ * still fail. This implies that is a delay following invalidation
|
|
|
|
+ * that is required to reset the caches as opposed to a delay to
|
|
|
|
+ * ensure the memory is written.
|
|
|
|
+ */
|
|
|
|
+ if (mode & EMIT_INVALIDATE) {
|
|
|
|
+ *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE;
|
|
|
|
+ *cs++ = i915_ggtt_offset(rq->engine->scratch) |
|
|
|
|
+ PIPE_CONTROL_GLOBAL_GTT;
|
|
|
|
+ *cs++ = 0;
|
|
|
|
+ *cs++ = 0;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < 12; i++)
|
|
|
|
+ *cs++ = MI_FLUSH;
|
|
|
|
+
|
|
|
|
+ *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE;
|
|
|
|
+ *cs++ = i915_ggtt_offset(rq->engine->scratch) |
|
|
|
|
+ PIPE_CONTROL_GLOBAL_GTT;
|
|
|
|
+ *cs++ = 0;
|
|
|
|
+ *cs++ = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ *cs++ = cmd;
|
|
|
|
+
|
|
intel_ring_advance(rq, cs);
|
|
intel_ring_advance(rq, cs);
|
|
|
|
|
|
return 0;
|
|
return 0;
|