From e3a6e60040b7f6ea7965e52f8f9881ed31e0347c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 7 Dec 2007 16:15:49 -0800 Subject: [965] Convert the driver to dri_bufmgr interface and enable TTM. This is currently believed to work but be a significant performance loss. Performance recovery should be soon to follow. The dri_bo_fake_disable_backing_store() call was added to allow backing store disable like bufmgr_fake.c did, which is a significant performance win (though it's missing the no-fence-subdata part). This commit is a squash merge of the 965-ttm branch, which had some history I wanted to avoid pulling due to noisiness and brokenness at many points for git-bisecting. --- src/mesa/drivers/dri/i965/intel_ioctl.c | 139 ++++++++++++++++++-------------- 1 file changed, 78 insertions(+), 61 deletions(-) (limited to 'src/mesa/drivers/dri/i965/intel_ioctl.c') diff --git a/src/mesa/drivers/dri/i965/intel_ioctl.c b/src/mesa/drivers/dri/i965/intel_ioctl.c index e7e736079f..50ad4e4f1f 100644 --- a/src/mesa/drivers/dri/i965/intel_ioctl.c +++ b/src/mesa/drivers/dri/i965/intel_ioctl.c @@ -41,43 +41,36 @@ #include "intel_blit.h" #include "intel_regions.h" #include "drm.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" +#include "intel_bufmgr_ttm.h" +#include "i915_drm.h" -static int intelWaitIdleLocked( struct intel_context *intel ) +static void intelWaitIdleLocked( struct intel_context *intel ) { - static int in_wait_idle = 0; unsigned int fence; - if (!in_wait_idle) { - if (INTEL_DEBUG & DEBUG_SYNC) { - fprintf(stderr, "waiting for idle\n"); - } - - in_wait_idle = 1; - fence = bmSetFence(intel); - intelWaitIrq(intel, fence); - in_wait_idle = 0; + if (INTEL_DEBUG & DEBUG_SYNC) + fprintf(stderr, "waiting for idle\n"); - return bmTestFence(intel, fence); - } else { - return 1; - } + fence = intelEmitIrqLocked(intel->intelScreen); + intelWaitIrq(intel->intelScreen, fence); } -int intelEmitIrqLocked( struct intel_context *intel ) +int intelEmitIrqLocked( intelScreenPrivate *intelScreen ) { int seq = 1; - if (!intel->no_hw) { + if (!intelScreen->no_hw) { drmI830IrqEmit ie; int ret; - + /* assert(((*(int *)intel->driHwLock) & ~DRM_LOCK_CONT) == (DRM_LOCK_HELD|intel->hHWContext)); - + */ ie.irq_seq = &seq; - ret = drmCommandWriteRead( intel->driFd, DRM_I830_IRQ_EMIT, + ret = drmCommandWriteRead( intelScreen->driScrnPriv->fd, + DRM_I830_IRQ_EMIT, &ie, sizeof(ie) ); if ( ret ) { fprintf( stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret ); @@ -91,26 +84,32 @@ int intelEmitIrqLocked( struct intel_context *intel ) return seq; } -void intelWaitIrq( struct intel_context *intel, int seq ) +void intelWaitIrq( intelScreenPrivate *intelScreen, int seq ) { - if (!intel->no_hw) { + if (!intelScreen->no_hw) { drmI830IrqWait iw; int ret, lastdispatch; - + volatile drmI830Sarea *sarea = (volatile drmI830Sarea *) + (((GLubyte *)intelScreen->driScrnPriv->pSAREA) + + intelScreen->sarea_priv_offset); + if (0) fprintf(stderr, "%s %d\n", __FUNCTION__, seq ); iw.irq_seq = seq; do { - lastdispatch = intel->sarea->last_dispatch; - ret = drmCommandWrite( intel->driFd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw) ); + lastdispatch = sarea->last_dispatch; + ret = drmCommandWrite( intelScreen->driScrnPriv->fd, + DRM_I830_IRQ_WAIT, &iw, sizeof(iw) ); /* This seems quite often to return before it should!?! */ - } while (ret == -EAGAIN || ret == -EINTR || (ret == -EBUSY && lastdispatch != intel->sarea->last_dispatch) || (ret == 0 && seq > intel->sarea->last_dispatch) - || (ret == 0 && intel->sarea->last_dispatch - seq >= (1 << 24))); - + } while (ret == -EAGAIN || + ret == -EINTR || + (ret == -EBUSY && lastdispatch != sarea->last_dispatch) || + (ret == 0 && seq > sarea->last_dispatch) || + (ret == 0 && sarea->last_dispatch - seq >= (1 << 24))); if ( ret ) { fprintf( stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret ); @@ -123,7 +122,9 @@ void intelWaitIrq( struct intel_context *intel, int seq ) void intel_batch_ioctl( struct intel_context *intel, GLuint start_offset, - GLuint used) + GLuint used, + GLboolean ignore_cliprects, + GLboolean allow_unlock ) { drmI830BatchBuffer batch; @@ -150,52 +151,68 @@ void intel_batch_ioctl( struct intel_context *intel, batch.start, batch.start + batch.used * 4); - if (!intel->no_hw) { + if (!intel->intelScreen->no_hw) { if (drmCommandWrite (intel->driFd, DRM_I830_BATCHBUFFER, &batch, sizeof(batch))) { fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n", -errno); UNLOCK_HARDWARE(intel); exit(1); } - - if (INTEL_DEBUG & DEBUG_SYNC) { - intelWaitIdleLocked(intel); - } } } -void intel_cmd_ioctl( struct intel_context *intel, - char *buf, - GLuint used) +void +intel_exec_ioctl(struct intel_context *intel, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock, + void *start, GLuint count, dri_fence **fence) { - drmI830CmdBuffer cmd; + struct drm_i915_execbuffer execbuf; + dri_fence *fo; assert(intel->locked); assert(used); - cmd.buf = buf; - cmd.sz = used; - cmd.cliprects = intel->pClipRects; - cmd.num_cliprects = 0; - cmd.DR1 = 0; - cmd.DR4 = 0; - - if (INTEL_DEBUG & DEBUG_DMA) - fprintf(stderr, "%s: 0x%x..0x%x\n", - __FUNCTION__, - 0, - 0 + cmd.sz); + if (*fence) { + dri_fence_unreference(*fence); + } - if (!intel->no_hw) { - if (drmCommandWrite (intel->driFd, DRM_I830_CMDBUFFER, &cmd, - sizeof(cmd))) { - fprintf(stderr, "DRM_I830_CMDBUFFER: %d\n", -errno); - UNLOCK_HARDWARE(intel); - exit(1); - } + memset(&execbuf, 0, sizeof(execbuf)); - if (INTEL_DEBUG & DEBUG_SYNC) { - intelWaitIdleLocked(intel); - } + execbuf.num_buffers = count; + execbuf.batch.used = used; + execbuf.batch.cliprects = intel->pClipRects; + execbuf.batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; + execbuf.batch.DR1 = 0; + execbuf.batch.DR4 = ((((GLuint) intel->drawX) & 0xffff) | + (((GLuint) intel->drawY) << 16)); + + execbuf.ops_list = (unsigned)start; // TODO + execbuf.fence_arg.flags = DRM_FENCE_FLAG_SHAREABLE | DRM_I915_FENCE_FLAG_FLUSHED; + + if (intel->intelScreen->no_hw) + return; + + if (drmCommandWriteRead(intel->driFd, DRM_I915_EXECBUFFER, &execbuf, + sizeof(execbuf))) { + fprintf(stderr, "DRM_I830_EXECBUFFER: %d\n", -errno); + UNLOCK_HARDWARE(intel); + exit(1); + } + + + fo = intel_ttm_fence_create_from_arg(intel->intelScreen->bufmgr, "fence buffers", + &execbuf.fence_arg); + if (!fo) { + fprintf(stderr, "failed to fence handle: %08x\n", execbuf.fence_arg.handle); + UNLOCK_HARDWARE(intel); + exit(1); } + *fence = fo; + + /* FIXME: use hardware contexts to avoid 'losing' hardware after + * each buffer flush. + */ + intel->vtbl.lost_hardware(intel); + } -- cgit v1.2.3