drm/i915: only one interrupt per batchbuffer is not enough!
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 2 Feb 2010 16:08:37 +0000 (17:08 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Wed, 8 Sep 2010 09:23:35 +0000 (10:23 +0100)
Previously I thought that one interrupt per batchbuffer should be
enough. Now tedious benchmarking showed this to be wrong.

Therefore track whether any commands have been isssued with a future
seqno (like pipelined fencing changes or flushes). If this is the case
emit a request before issueing the batchbuffer.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_ringbuffer.h

index 2692410..fb8d681 100644 (file)
@@ -293,9 +293,6 @@ typedef struct drm_i915_private {
        unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
        int vblank_pipe;
        int num_pipe;
-       u32 flush_rings;
-#define FLUSH_RENDER_RING      0x1
-#define FLUSH_BSD_RING         0x2
 
        /* For hangcheck timer */
 #define DRM_I915_HANGCHECK_PERIOD 75 /* in jiffies */
index eea8232..b52f47a 100644 (file)
@@ -1470,10 +1470,13 @@ i915_gem_object_put_pages(struct drm_gem_object *obj)
 }
 
 static uint32_t
-i915_gem_next_request_seqno(struct drm_device *dev)
+i915_gem_next_request_seqno(struct drm_device *dev,
+                           struct intel_ring_buffer *ring)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
 
+       ring->outstanding_lazy_request = true;
+
        return dev_priv->next_seqno;
 }
 
@@ -1495,7 +1498,7 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno,
 
        /* Take the seqno of the next request if none is given */
        if (seqno == 0)
-               seqno = i915_gem_next_request_seqno(dev);
+               seqno = i915_gem_next_request_seqno(dev, ring);
 
        /* Move from whatever list we were on to the tail of execution. */
        spin_lock(&dev_priv->mm.active_list_lock);
@@ -2979,7 +2982,6 @@ static void
 i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
 {
        struct drm_device               *dev = obj->dev;
-       drm_i915_private_t              *dev_priv = dev->dev_private;
        struct drm_i915_gem_object      *obj_priv = to_intel_bo(obj);
        uint32_t                        invalidate_domains = 0;
        uint32_t                        flush_domains = 0;
@@ -3042,13 +3044,6 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
                obj->pending_write_domain = obj->write_domain;
        obj->read_domains = obj->pending_read_domains;
 
-       if (flush_domains & I915_GEM_GPU_DOMAINS) {
-               if (obj_priv->ring == &dev_priv->render_ring)
-                       dev_priv->flush_rings |= FLUSH_RENDER_RING;
-               else if (obj_priv->ring == &dev_priv->bsd_ring)
-                       dev_priv->flush_rings |= FLUSH_BSD_RING;
-       }
-
        dev->invalidate_domains |= invalidate_domains;
        dev->flush_domains |= flush_domains;
 #if WATCH_BUF
@@ -3762,7 +3757,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
         */
        dev->invalidate_domains = 0;
        dev->flush_domains = 0;
-       dev_priv->flush_rings = 0;
 
        for (i = 0; i < args->buffer_count; i++) {
                struct drm_gem_object *obj = object_list[i];
@@ -3783,12 +3777,17 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
                i915_gem_flush(dev,
                               dev->invalidate_domains,
                               dev->flush_domains);
-               if (dev_priv->flush_rings & FLUSH_RENDER_RING)
-                       (void)i915_add_request(dev, file_priv, 0,
-                                              &dev_priv->render_ring);
-               if (dev_priv->flush_rings & FLUSH_BSD_RING)
-                       (void)i915_add_request(dev, file_priv, 0,
-                                              &dev_priv->bsd_ring);
+       }
+
+       if (dev_priv->render_ring.outstanding_lazy_request) {
+               (void)i915_add_request(dev, file_priv, 0,
+                                      &dev_priv->render_ring);
+               dev_priv->render_ring.outstanding_lazy_request = false;
+       }
+       if (dev_priv->bsd_ring.outstanding_lazy_request) {
+               (void)i915_add_request(dev, file_priv, 0,
+                                      &dev_priv->bsd_ring);
+               dev_priv->bsd_ring.outstanding_lazy_request = false;
        }
 
        for (i = 0; i < args->buffer_count; i++) {
index 525e7d3..d3e5f40 100644 (file)
@@ -83,6 +83,11 @@ struct  intel_ring_buffer {
         */
        struct list_head request_list;
 
+       /**
+        * Do we have some not yet emitted requests outstanding?
+        */
+       bool outstanding_lazy_request;
+
        wait_queue_head_t irq_queue;
        drm_local_map_t map;
 };