summaryrefslogtreecommitdiff
path: root/linux-core/i915_fence.c
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2006-09-15 11:18:35 +0200
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2006-09-15 11:18:35 +0200
commit49fbeb339c232804866cd548d6023fe559597353 (patch)
treefa4685050d7a91a7ee0e55f10093b4fa403a61aa /linux-core/i915_fence.c
parent7223b4e264a64df2df70715d8777f2ccaa883d5e (diff)
Some bugfixes.
Change the fence object interface somewhat to allow some more flexibility. Make list IOCTLS really restartable. Try to avoid busy-waits in the kernel using immediate return to user-space with an -EAGAIN.
Diffstat (limited to 'linux-core/i915_fence.c')
-rw-r--r--linux-core/i915_fence.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/linux-core/i915_fence.c b/linux-core/i915_fence.c
index 20e12d6a..5a8612cb 100644
--- a/linux-core/i915_fence.c
+++ b/linux-core/i915_fence.c
@@ -43,7 +43,6 @@ static void i915_perform_flush(drm_device_t * dev)
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
drm_fence_manager_t *fm = &dev->fm;
drm_fence_driver_t *driver = dev->driver->fence_driver;
- int flush_completed = 0;
uint32_t flush_flags = 0;
uint32_t flush_sequence = 0;
uint32_t i_status;
@@ -52,9 +51,14 @@ static void i915_perform_flush(drm_device_t * dev)
if (fm->pending_exe_flush) {
sequence = READ_BREADCRUMB(dev_priv);
+
+ /*
+ * First update fences with the current breadcrumb.
+ */
+
diff = sequence - fm->last_exe_flush;
if (diff < driver->wrap_diff && diff != 0) {
- drm_fence_handler(dev, sequence, DRM_FENCE_EXE);
+ drm_fence_handler(dev, sequence, DRM_FENCE_TYPE_EXE);
}
diff = sequence - fm->exe_flush_sequence;
@@ -69,20 +73,18 @@ static void i915_perform_flush(drm_device_t * dev)
dev_priv->fence_irq_on = 1;
}
}
+
if (dev_priv->flush_pending) {
i_status = READ_HWSP(dev_priv, 0);
if ((i_status & (1 << 12)) !=
(dev_priv->saved_flush_status & (1 << 12))) {
- flush_completed = 1;
flush_flags = dev_priv->flush_flags;
flush_sequence = dev_priv->flush_sequence;
dev_priv->flush_pending = 0;
- } else {
- }
- }
- if (flush_completed) {
- drm_fence_handler(dev, flush_sequence, flush_flags);
+ drm_fence_handler(dev, flush_sequence, flush_flags);
+ }
}
+
if (fm->pending_flush && !dev_priv->flush_pending) {
dev_priv->flush_sequence = (uint32_t) READ_BREADCRUMB(dev_priv);
dev_priv->flush_flags = fm->pending_flush;
@@ -91,6 +93,18 @@ static void i915_perform_flush(drm_device_t * dev)
dev_priv->flush_pending = 1;
fm->pending_flush = 0;
}
+
+ if (dev_priv->flush_pending) {
+ i_status = READ_HWSP(dev_priv, 0);
+ if ((i_status & (1 << 12)) !=
+ (dev_priv->saved_flush_status & (1 << 12))) {
+ flush_flags = dev_priv->flush_flags;
+ flush_sequence = dev_priv->flush_sequence;
+ dev_priv->flush_pending = 0;
+ drm_fence_handler(dev, flush_sequence, flush_flags);
+ }
+ }
+
}
void i915_poke_flush(drm_device_t * dev)
@@ -117,7 +131,6 @@ void i915_fence_handler(drm_device_t * dev)
write_lock(&fm->lock);
i915_perform_flush(dev);
- i915_perform_flush(dev);
write_unlock(&fm->lock);
}