[intel-gem] Force ring retire by emiting flush before user-interrupt.
authorKeith Packard <keithp@keithp.com>
Thu, 22 May 2008 17:59:59 +0000 (10:59 -0700)
committerEric Anholt <eric@anholt.net>
Fri, 23 May 2008 05:00:21 +0000 (22:00 -0700)
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).

linux-core/i915_gem.c

index 469b613..3214707 100644 (file)
@@ -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