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:
parent
612c1f1f18
commit
d82ea4372f
|
|
@ -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() */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue