diff options
-rw-r--r-- | src/i830.h | 1 | ||||
-rw-r--r-- | src/i830_accel.c | 31 | ||||
-rw-r--r-- | src/i830_batchbuffer.c | 29 | ||||
-rw-r--r-- | src/i830_batchbuffer.h | 1 |
4 files changed, 30 insertions, 32 deletions
@@ -385,6 +385,7 @@ typedef struct _I830Rec { /** Number of bytes to be emitted in the current BEGIN_BATCH. */ uint32_t batch_emitting; dri_bo *batch_bo; + dri_bo *last_batch_bo; /** Whether we're in a section of code that can't tolerate flushing */ Bool in_batch_atomic; /** Ending batch_used that was verified by i830_start_batch_atomic() */ diff --git a/src/i830_accel.c b/src/i830_accel.c index c2f30a8b..589f86de 100644 --- a/src/i830_accel.c +++ b/src/i830_accel.c @@ -156,36 +156,7 @@ I830Sync(ScrnInfoPtr pScrn) I830EmitFlush(pScrn); intel_batch_flush(pScrn, TRUE); - - if (pI830->directRenderingType > DRI_NONE) { - struct drm_i915_irq_emit emit; - struct drm_i915_irq_wait wait; - int ret; - - /* Most of the uses of I830Sync while using GEM should actually be - * using set_domain on a specific buffer. We're not there yet, so fake - * it up using irq_emit/wait. It's still better than spinning on - * register reads for idle. - */ - emit.irq_seq = &wait.irq_seq; - ret = drmCommandWriteRead(pI830->drmSubFD, DRM_I830_IRQ_EMIT, &emit, - sizeof(emit)); - if (ret != 0) - FatalError("Failure to emit IRQ: %s\n", strerror(-ret)); - - do { - ret = drmCommandWrite(pI830->drmSubFD, DRM_I830_IRQ_WAIT, &wait, - sizeof(wait)); - } while (ret == -EINTR); - - if (ret != 0) - FatalError("Failure to wait for IRQ: %s\n", strerror(-ret)); - - if (!pI830->memory_manager) - i830_refresh_ring(pScrn); - } else if (!pI830->use_drm_mode) { - i830_wait_ring_idle(pScrn); - } + intel_batch_wait_last(pScrn); } void diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c index ff5f0c21..5a9f9c5c 100644 --- a/src/i830_batchbuffer.c +++ b/src/i830_batchbuffer.c @@ -159,8 +159,13 @@ intel_batch_teardown(ScrnInfoPtr pScrn) if (pI830->batch_ptr != NULL) { dri_bo_unmap(pI830->batch_bo); - dri_bo_unreference(pI830->batch_bo); pI830->batch_ptr = NULL; + + dri_bo_unreference(pI830->batch_bo); + pI830->batch_bo = NULL; + + dri_bo_unreference(pI830->last_batch_bo); + pI830->last_batch_bo = NULL; } } @@ -201,7 +206,13 @@ intel_batch_flush(ScrnInfoPtr pScrn, Bool flushed) if (ret != 0) FatalError("Failed to submit batchbuffer: %s\n", strerror(-ret)); - dri_bo_unreference(pI830->batch_bo); + /* Save a ref to the last batch emitted, which we use for syncing + * in debug code. + */ + dri_bo_unreference(pI830->last_batch_bo); + pI830->last_batch_bo = pI830->batch_bo; + pI830->batch_bo = NULL; + intel_next_batch(pScrn); /* Mark that we need to flush whatever potential rendering we've done in the @@ -214,3 +225,17 @@ intel_batch_flush(ScrnInfoPtr pScrn, Bool flushed) if (pI830->batch_flush_notify) pI830->batch_flush_notify (pScrn); } + +/** Waits on the last emitted batchbuffer to be completed. */ +void +intel_batch_wait_last(ScrnInfoPtr scrn) +{ + I830Ptr pI830 = I830PTR(scrn); + + /* Map it CPU write, which guarantees it's done. This is a completely + * non performance path, so we don't need anything better. + */ + drm_intel_bo_map(pI830->last_batch_bo, TRUE); + drm_intel_bo_unmap(pI830->last_batch_bo); +} + diff --git a/src/i830_batchbuffer.h b/src/i830_batchbuffer.h index d0114176..81e84e2a 100644 --- a/src/i830_batchbuffer.h +++ b/src/i830_batchbuffer.h @@ -35,6 +35,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. void intel_batch_init(ScrnInfoPtr pScrn); void intel_batch_teardown(ScrnInfoPtr pScrn); void intel_batch_flush(ScrnInfoPtr pScrn, Bool flushed); +void intel_batch_wait_last(ScrnInfoPtr pScrn); static inline int intel_batch_space(I830Ptr pI830) |