summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-05-22 10:59:59 -0700
committerEric Anholt <eric@anholt.net>2008-05-22 22:00:21 -0700
commit71b09a5f75c6063a592f7be07465761519839bcd (patch)
tree5872a055f135fb77b844681388a87c0f094ba891
parenta51c3a76ff415104426493a97ac686ccfe3f3926 (diff)
[intel-gem] Force ring retire by emiting flush before user-interrupt.
Commands in the ring are parsed and started when the head pointer passes by them, but they are not necessarily finished until a MI_FLUSH happens. This patch inserts a flush after the execbuffer (the only place a flush wasn't already happening).
-rw-r--r--linux-core/i915_gem.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c
index 469b613f..3214707f 100644
--- a/linux-core/i915_gem.c
+++ b/linux-core/i915_gem.c
@@ -162,6 +162,31 @@ i915_add_request(struct drm_device *dev, uint32_t flush_domains)
}
/**
+ * Command execution barrier
+ *
+ * Ensures that all commands in the ring are finished
+ * before signalling the CPU
+ */
+
+uint32_t
+i915_retire_commands(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ uint32_t cmd = CMD_MI_FLUSH | MI_NO_WRITE_FLUSH;
+ uint32_t flush_domains = 0;
+ RING_LOCALS;
+
+ /* The sampler always gets flushed on i965 (sigh) */
+ if (IS_I965G(dev))
+ flush_domains |= DRM_GEM_DOMAIN_I915_SAMPLER;
+ BEGIN_LP_RING(2);
+ OUT_RING(cmd);
+ OUT_RING(0); /* noop */
+ ADVANCE_LP_RING();
+ return flush_domains;
+}
+
+/**
* Moves buffers associated only with the given active seqno from the active
* to inactive list, potentially freeing them.
*/
@@ -359,6 +384,9 @@ i915_gem_flush(struct drm_device *dev,
if (invalidate_domains & DRM_GEM_DOMAIN_I915_INSTRUCTION)
cmd |= MI_EXE_FLUSH;
+#if WATCH_EXEC
+ DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd);
+#endif
BEGIN_LP_RING(2);
OUT_RING(cmd);
OUT_RING(0); /* noop */
@@ -1202,6 +1230,12 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
}
/*
+ * Ensure that the commands in the batch buffer are
+ * finished before the interrupt fires
+ */
+ flush_domains |= i915_retire_commands(dev);
+
+ /*
* Get a seqno representing the execution of the current buffer,
* which we can wait on. We would like to mitigate these interrupts,
* likely by only creating seqnos occasionally (so that we have