summaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-06-13 12:06:13 -0700
committerKeith Packard <keithp@keithp.com>2008-06-13 14:29:46 -0700
commitced9ebf64543b4d64a38feee3293040af953acc0 (patch)
treecb4027ab95b482f6d8840eedf6c5559cb5578143 /linux-core
parent6b2cba1ecc5f9f289b5d91e229b7f7b0999bee5b (diff)
[intel-gem] throttle based on frames rather than time. Reduces jitter.
Record the last execbuffer sequence for each client. Record that sequence in the throttle ioctl as the 'throttle sequence'. Wait for the last throttle sequence in the throttle ioctl.
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/i915_drv.c3
-rw-r--r--linux-core/i915_gem.c34
2 files changed, 13 insertions, 24 deletions
diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c
index 89f089b0..012ca822 100644
--- a/linux-core/i915_drv.c
+++ b/linux-core/i915_drv.c
@@ -561,6 +561,7 @@ static int i915_resume(struct drm_device *dev)
static int probe(struct pci_dev *pdev, const struct pci_device_id *ent);
static void remove(struct pci_dev *pdev);
+
static struct drm_driver driver = {
/* don't use mtrr's here, the Xserver or user space app should
* deal with them for intel hardware.
@@ -571,8 +572,10 @@ static struct drm_driver driver = {
.load = i915_driver_load,
.unload = i915_driver_unload,
.firstopen = i915_driver_firstopen,
+ .open = i915_driver_open,
.lastclose = i915_driver_lastclose,
.preclose = i915_driver_preclose,
+ .postclose = i915_driver_postclose,
.suspend = i915_suspend,
.resume = i915_resume,
.device_is_agp = i915_driver_device_is_agp,
diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c
index b114192d..c2d1fab6 100644
--- a/linux-core/i915_gem.c
+++ b/linux-core/i915_gem.c
@@ -1548,33 +1548,17 @@ i915_dispatch_gem_execbuffer(struct drm_device *dev,
* relatively low latency when blocking on a particular request to finish.
*/
static int
-i915_gem_ring_throttle(struct drm_device *dev)
+i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
int ret = 0;
+ uint32_t seqno;
mutex_lock(&dev->struct_mutex);
- while (!list_empty(&dev_priv->mm.request_list)) {
- struct drm_i915_gem_request *request;
-
- request = list_first_entry(&dev_priv->mm.request_list,
- struct drm_i915_gem_request,
- list);
-
- /* Break out if we're close enough. */
- if ((long) (jiffies - request->emitted_jiffies) <=
- (20 * HZ) / 1000) {
- mutex_unlock(&dev->struct_mutex);
- return 0;
- }
-
- /* Wait on the last request if not. */
- ret = i915_wait_request(dev, request->seqno);
- if (ret != 0) {
- mutex_unlock(&dev->struct_mutex);
- return ret;
- }
- }
+ seqno = i915_file_priv->mm.last_gem_throttle_seqno;
+ i915_file_priv->mm.last_gem_throttle_seqno = i915_file_priv->mm.last_gem_seqno;
+ if (seqno)
+ ret = i915_wait_request(dev, seqno);
mutex_unlock(&dev->struct_mutex);
return ret;
}
@@ -1584,6 +1568,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
struct drm_i915_gem_execbuffer *args = data;
struct drm_i915_gem_exec_object *exec_list = NULL;
struct drm_gem_object **object_list = NULL;
@@ -1724,6 +1709,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
*/
seqno = i915_add_request(dev, flush_domains);
BUG_ON(seqno == 0);
+ i915_file_priv->mm.last_gem_seqno = seqno;
for (i = 0; i < args->buffer_count; i++) {
struct drm_gem_object *obj = object_list[i];
struct drm_i915_gem_object *obj_priv = obj->driver_private;
@@ -1881,7 +1867,7 @@ int
i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- return i915_gem_ring_throttle(dev);
+ return i915_gem_ring_throttle(dev, file_priv);
}
int i915_gem_init_object(struct drm_gem_object *obj)