Replace I830Sync's irq emit/wait code with bufmgr use.

This pre-GEM code was all sorts of broken -- see intel_bufmgr_fake.c for
the hoops that must be jumped to use that kernel interface successfully.
Yet we continued to use it even with KMS/DRI2/UXA, which may account for
some hangs.
This commit is contained in:
Eric Anholt 2009-04-20 13:20:03 -07:00
parent 612c1f1f18
commit d82ea4372f
4 changed files with 30 additions and 32 deletions

View File

@ -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() */

View File

@ -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

View File

@ -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);
}

View File

@ -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)