[gem] Replace ring throttling hack with actual time measurement.

main
Eric Anholt 2008-05-20 16:27:05 -07:00
parent 54fa32cdfe
commit d6f7968577
2 changed files with 30 additions and 22 deletions

View File

@ -154,6 +154,7 @@ i915_add_request(struct drm_device *dev)
DRM_DEBUG("%d\n", seqno); DRM_DEBUG("%d\n", seqno);
request->seqno = seqno; request->seqno = seqno;
request->emitted_jiffies = jiffies;
list_add_tail(&request->list, &dev_priv->mm.request_list); list_add_tail(&request->list, &dev_priv->mm.request_list);
return seqno; return seqno;
@ -966,34 +967,38 @@ i915_dispatch_gem_execbuffer(struct drm_device *dev,
return 0; return 0;
} }
/* /* Throttle our rendering by waiting until the ring has completed our requests
* Kludge -- wait for almost all rendering to complete * emitted over 20 msec ago.
* before queuing more. This uses interrupts, so the wakeup *
* occurs without any delay. * This should get us reasonable parallelism between CPU and GPU but also
* relatively low latency when blocking on a particular request to finish.
*/ */
static int static int
i915_gem_wait_space(struct drm_device *dev) i915_gem_ring_throttle(struct drm_device *dev)
{ {
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
struct drm_i915_gem_object *obj_priv, *last_priv = NULL;
int ret = 0; int ret = 0;
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
while (ring->space + 1024 < dev_priv->ring.Size && while (!list_empty(&dev_priv->mm.request_list)) {
!list_empty(&dev_priv->mm.active_list)) { struct drm_i915_gem_request *request;
obj_priv = list_first_entry(&dev_priv->mm.active_list,
struct drm_i915_gem_object, request = list_first_entry(&dev_priv->mm.request_list,
list); struct drm_i915_gem_request,
if (obj_priv == last_priv) list);
break;
drm_gem_object_reference(obj_priv->obj); /* Break out if we're close enough. */
ret = i915_gem_object_wait_rendering(obj_priv->obj); if (jiffies_to_msecs(jiffies - request->emitted_jiffies) < 20) {
drm_gem_object_unreference(obj_priv->obj); mutex_unlock(&dev->struct_mutex);
if (ret) return 0;
break; }
last_priv = obj_priv;
i915_kernel_lost_context(dev); /* Wait on the last request if not. */
ret = i915_wait_request(dev, request->seqno);
if (ret != 0) {
mutex_unlock(&dev->struct_mutex);
return ret;
}
} }
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
return ret; return ret;
@ -1019,7 +1024,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
#endif #endif
i915_kernel_lost_context(dev); i915_kernel_lost_context(dev);
ret = i915_gem_wait_space(dev); ret = i915_gem_ring_throttle(dev);
if (ret) if (ret)
return ret; return ret;

View File

@ -331,6 +331,9 @@ struct drm_i915_gem_request {
/** GEM sequence number associated with this request. */ /** GEM sequence number associated with this request. */
uint32_t seqno; uint32_t seqno;
/** Time at which this request was emitted, in jiffies. */
unsigned long emitted_jiffies;
struct list_head list; struct list_head list;
}; };