diff options
author | Thomas Hellström <thomas@tungstengraphics.com> | 2006-09-18 14:11:00 +0000 |
---|---|---|
committer | Thomas Hellström <thomas@tungstengraphics.com> | 2006-09-18 14:11:00 +0000 |
commit | 8c58a32360b1e8591dbf2f28aa5b804892187f6a (patch) | |
tree | 7efa361cf38e810d8966abbe9a5617ce7d7d491b /src | |
parent | 0d646ea3a860bf3b456e3270b368a1b76729a380 (diff) |
Fix fencing when submitting empty batchbuffers.
Add a proper buffer waitidle method.
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/drivers/dri/common/dri_bufmgr.c | 26 | ||||
-rw-r--r-- | src/mesa/drivers/dri/common/dri_bufmgr.h | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/common/dri_bufpool.h | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/common/dri_drmpool.c | 12 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_batchbuffer.c | 38 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_batchpool.c | 8 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_buffers.c | 5 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_context.c | 9 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_regions.c | 3 |
9 files changed, 76 insertions, 30 deletions
diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.c b/src/mesa/drivers/dri/common/dri_bufmgr.c index db607a74cd..0387c7a927 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr.c @@ -79,7 +79,7 @@ bmError(int val, const char *file, const char *function, int line) "Detected in file %s, line %d, function %s.\n", strerror(-val), file, line, function); #ifndef NDEBUG - exit(-1); + abort(); #else abort(); #endif @@ -109,6 +109,19 @@ driFenceBuffers(int fd, char *name, unsigned flags) } +unsigned +driFenceType(DriFenceObject * fence) +{ + unsigned ret; + + _glthread_LOCK_MUTEX(bmMutex); + ret = fence->fence.flags; + _glthread_UNLOCK_MUTEX(bmMutex); + + return ret; +} + + void driFenceReference(DriFenceObject * fence) { @@ -159,6 +172,7 @@ driFenceSignaled(DriFenceObject * fence, unsigned type) return signaled; } + extern drmBO * driBOKernel(struct _DriBufferObject *buf) { @@ -172,6 +186,16 @@ driBOKernel(struct _DriBufferObject *buf) return ret; } +void +driBOWaitIdle(struct _DriBufferObject *buf, int lazy) +{ + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, lazy)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + void * driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) { diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.h b/src/mesa/drivers/dri/common/dri_bufmgr.h index c742029135..0ee5867d2d 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.h +++ b/src/mesa/drivers/dri/common/dri_bufmgr.h @@ -50,6 +50,7 @@ extern void driFenceFinish(struct _DriFenceObject *fence, unsigned type, int lazy); extern int driFenceSignaled(struct _DriFenceObject *fence, unsigned type); +extern unsigned driFenceType(struct _DriFenceObject *fence); /* * Return a pointer to the libdrm buffer object this DriBufferObject @@ -92,5 +93,7 @@ extern void driPoolTakeDown(struct _DriBufferPool *pool); extern void driBOSetStatic(struct _DriBufferObject *buf, unsigned long offset, unsigned long size, void *virtual, unsigned flags); +extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy); + #endif diff --git a/src/mesa/drivers/dri/common/dri_bufpool.h b/src/mesa/drivers/dri/common/dri_bufpool.h index 98b0d031b5..c6fb2c3ce0 100644 --- a/src/mesa/drivers/dri/common/dri_bufpool.h +++ b/src/mesa/drivers/dri/common/dri_bufpool.h @@ -53,6 +53,8 @@ typedef struct _DriBufferPool int (*validate) (struct _DriBufferPool * pool, void *private); void *(*setstatic) (struct _DriBufferPool * pool, unsigned long offset, unsigned long size, void *virtual, unsigned flags); + int (*waitIdle) (struct _DriBufferPool *pool, void *private, + int lazy); void (*takeDown) (struct _DriBufferPool * pool); void *data; } DriBufferPool; diff --git a/src/mesa/drivers/dri/common/dri_drmpool.c b/src/mesa/drivers/dri/common/dri_drmpool.c index 845b604784..e69a738b1c 100644 --- a/src/mesa/drivers/dri/common/dri_drmpool.c +++ b/src/mesa/drivers/dri/common/dri_drmpool.c @@ -124,7 +124,15 @@ pool_kernel(struct _DriBufferPool *pool, void *private) return (drmBO *) private; } -void +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy) +{ + drmBO *buf = (drmBO *) private; + return drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); +} + + +static void pool_takedown(struct _DriBufferPool *pool) { free(pool); @@ -153,6 +161,7 @@ driDRMPoolInit(int fd) pool->kernel = &pool_kernel; pool->validate = NULL; pool->setstatic = NULL; + pool->waitIdle = &pool_waitIdle; pool->takeDown = &pool_takedown; pool->data = NULL; return pool; @@ -205,6 +214,7 @@ driDRMStaticPoolInit(int fd) pool->kernel = &pool_kernel; pool->validate = NULL; pool->setstatic = &pool_setstatic; + pool->waitIdle = &pool_waitIdle; pool->takeDown = &pool_takedown; pool->data = NULL; return pool; diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.c b/src/mesa/drivers/dri/i915/intel_batchbuffer.c index ee96fd8579..87969900b3 100644 --- a/src/mesa/drivers/dri/i915/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.c @@ -166,6 +166,7 @@ do_flush_locked(struct intel_batchbuffer *batch, GLuint i; struct intel_context *intel = batch->intel; unsigned fenceFlags; + struct _DriFenceObject *fo; driBOValidateList(batch->intel->driFd, &batch->list); @@ -189,23 +190,6 @@ do_flush_locked(struct intel_batchbuffer *batch, driBOUnmap(batch->buffer); batch->map = NULL; - /* Fire the batch buffer, which was uploaded above: - */ - -#if 0 - { - void *iterator = drmBOListIterator(&batch->list); - - _mesa_printf("\n"); - while (iterator != NULL) { - _mesa_printf("0x%08x\n", drmBOListBuf(iterator)->offset); - iterator = drmBOListNext(&batch->list, iterator); - } - _mesa_printf("Submitting 0x%08x\n", driBOOffset(batch->buffer)); - - } -#endif - /* Throw away non-effective packets. Won't work once we have * hardware contexts which would preserve statechanges beyond a * single buffer. @@ -217,7 +201,6 @@ do_flush_locked(struct intel_batchbuffer *batch, used, ignore_cliprects, allow_unlock); } - driFenceUnReference(batch->last_fence); /* * Kernel fencing. The flags tells the kernel that we've @@ -225,19 +208,32 @@ do_flush_locked(struct intel_batchbuffer *batch, */ fenceFlags = DRM_I915_FENCE_FLAG_FLUSHED; - batch->last_fence = driFenceBuffers(batch->intel->driFd, - "Batch fence", fenceFlags); + fo = driFenceBuffers(batch->intel->driFd, + "Batch fence", fenceFlags); /* * User space fencing. */ - driBOFence(batch->buffer, batch->last_fence); + driBOFence(batch->buffer, fo); for (i = 0; i < batch->nr_relocs; i++) { struct buffer_reloc *r = &batch->reloc[i]; driBOFence(r->buf, batch->last_fence); } + if (driFenceType(fo) == DRM_FENCE_TYPE_EXE) { + + /* + * Oops. We only validated a batch buffer. This means we + * didn't do any proper rendering. Discard this fence object. + */ + + driFenceUnReference(fo); + } else { + driFenceUnReference(batch->last_fence); + batch->last_fence = fo; + } + if (intel->numClipRects == 0 && !ignore_cliprects) { if (allow_unlock) { UNLOCK_HARDWARE(intel); diff --git a/src/mesa/drivers/dri/i915/intel_batchpool.c b/src/mesa/drivers/dri/i915/intel_batchpool.c index 1011e2f5ed..8f9a54470e 100644 --- a/src/mesa/drivers/dri/i915/intel_batchpool.c +++ b/src/mesa/drivers/dri/i915/intel_batchpool.c @@ -278,6 +278,13 @@ pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, } static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy) +{ + BBuf *buf = (BBuf *) private; + driFenceFinish(buf->fence, 0, lazy); +} + +static int pool_unmap(struct _DriBufferPool *pool, void *private) { BBuf *buf = (BBuf *) private; @@ -400,6 +407,7 @@ driBatchPoolInit(int fd, unsigned flags, pool->fence = &pool_fence; pool->kernel = &pool_kernel; pool->validate = &pool_validate; + pool->waitIdle = &pool_waitIdle; pool->setstatic = NULL; pool->takeDown = &pool_takedown; return pool; diff --git a/src/mesa/drivers/dri/i915/intel_buffers.c b/src/mesa/drivers/dri/i915/intel_buffers.c index 8022f17b71..c84f141c8c 100644 --- a/src/mesa/drivers/dri/i915/intel_buffers.c +++ b/src/mesa/drivers/dri/i915/intel_buffers.c @@ -696,9 +696,8 @@ void intelSwapBuffers(__DRIdrawablePrivate * dPriv) { if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { - struct intel_context *intel = - (struct intel_context *) dPriv->driContextPriv->driverPrivate; - GLcontext *ctx = &intel->ctx; + GET_CURRENT_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); if (ctx->Visual.doubleBufferMode) { intelScreenPrivate *screen = intel->intelScreen; diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index a9e7c8db78..ed2580948c 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -377,7 +377,7 @@ intelFinish(GLcontext * ctx) intelFlush(ctx); if (intel->batch->last_fence) { driFenceFinish(intel->batch->last_fence, - DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, GL_FALSE); + 0, GL_FALSE); driFenceUnReference(intel->batch->last_fence); intel->batch->last_fence = NULL; } @@ -575,6 +575,7 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) intel->Fallback = 0; /* don't call _swrast_Flush later */ intel_batchbuffer_free(intel->batch); + if (intel->last_swap_fence) { driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); driFenceUnReference(intel->last_swap_fence); @@ -713,7 +714,11 @@ intelGetLock(struct intel_context *intel, GLuint flags) sarea->rotation != intelScreen->current_rotation) { intelUpdateScreenRotation(intel, sPriv, sarea); - /* This will drop the outstanding batchbuffer on the floor */ + /* + * This will drop the outstanding batchbuffer on the floor + * FIXME: This should be done for all contexts? + */ + intel_batchbuffer_reset(intel->batch); /* lose all primitives */ diff --git a/src/mesa/drivers/dri/i915/intel_regions.c b/src/mesa/drivers/dri/i915/intel_regions.c index 12421c59e7..a86e70d053 100644 --- a/src/mesa/drivers/dri/i915/intel_regions.c +++ b/src/mesa/drivers/dri/i915/intel_regions.c @@ -52,8 +52,7 @@ void intel_region_idle(struct intel_context *intel, struct intel_region *region) { DBG("%s\n", __FUNCTION__); - if (driBOMap(region->buffer, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0)) - driBOUnmap(region->buffer); + driBOWaitIdle(region->buffer, GL_FALSE); } /* XXX: Thread safety? |