diff options
author | Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> | 2008-03-30 17:34:03 +0200 |
---|---|---|
committer | Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> | 2008-03-30 17:34:03 +0200 |
commit | 6b78eed962c65ff93b51ee1677ae3f73c7a18589 (patch) | |
tree | 11faca5964e5e15357497b3b03b862bd0952f03d | |
parent | 6c80f5876b0b00e6ba958e8aff9e31079cbcd681 (diff) |
Add proper waiting for unmap / fencing.
-rw-r--r-- | src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915tex/ws_dri_bufmgr.c | 20 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915tex/ws_dri_bufpool.h | 8 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915tex/ws_dri_drmpool.c | 5 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915tex/ws_dri_mallocpool.c | 14 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915tex/ws_dri_slabpool.c | 39 | ||||
-rw-r--r-- | src/mesa/glapi/glthread.h | 42 |
7 files changed, 98 insertions, 31 deletions
diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index 6b54bcfeac..757cbf1851 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -325,6 +325,7 @@ do_flush_locked(struct intel_batchbuffer *batch, if (batch->last_fence) driFenceUnReference(&batch->last_fence); + _mesa_printf("fence error\n"); batch->last_fence = NULL; return NULL; } diff --git a/src/mesa/drivers/dri/i915tex/ws_dri_bufmgr.c b/src/mesa/drivers/dri/i915tex/ws_dri_bufmgr.c index 97d7f3b7c7..ccbc855c55 100644 --- a/src/mesa/drivers/dri/i915tex/ws_dri_bufmgr.c +++ b/src/mesa/drivers/dri/i915tex/ws_dri_bufmgr.c @@ -337,7 +337,7 @@ driBOWaitIdle(struct _DriBufferObject *buf, int lazy) */ _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, lazy)); + BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, &buf->mutex, lazy)); _glthread_UNLOCK_MUTEX(buf->mutex); } @@ -349,7 +349,8 @@ driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) _glthread_LOCK_MUTEX(buf->mutex); assert(buf->private != NULL); - retval = buf->pool->map(buf->pool, buf->private, flags, hint, &virtual); + retval = buf->pool->map(buf->pool, buf->private, flags, hint, + &buf->mutex, &virtual); _glthread_UNLOCK_MUTEX(buf->mutex); return retval == 0 ? virtual : NULL; @@ -498,9 +499,9 @@ driBOData(struct _DriBufferObject *buf, if (retval == 0) retval = pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, - DRM_BO_HINT_DONT_BLOCK, &virtual); + DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual); } else if (pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, - DRM_BO_HINT_DONT_BLOCK, &virtual)) { + DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual)) { /* * Buffer is busy. need to create a new one. */ @@ -515,7 +516,7 @@ driBOData(struct _DriBufferObject *buf, } retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &virtual); + DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); } else { uint64_t flag_diff = flags ^ buf->flags; @@ -532,7 +533,7 @@ driBOData(struct _DriBufferObject *buf, goto out; retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &virtual); + DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); } } @@ -558,7 +559,8 @@ driBOSubData(struct _DriBufferObject *buf, _glthread_LOCK_MUTEX(buf->mutex); if (size && data) { BM_CKFATAL(buf->pool->map(buf->pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &virtual)); + DRM_BO_FLAG_WRITE, 0, &buf->mutex, + &virtual)); memcpy((unsigned char *) virtual + offset, data, size); BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); } @@ -574,7 +576,7 @@ driBOGetSubData(struct _DriBufferObject *buf, _glthread_LOCK_MUTEX(buf->mutex); if (size && data) { BM_CKFATAL(buf->pool->map(buf->pool, buf->private, - DRM_BO_FLAG_READ, 0, &virtual)); + DRM_BO_FLAG_READ, 0, &buf->mutex, &virtual)); memcpy(data, (unsigned char *) virtual + offset, size); BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); } @@ -876,7 +878,7 @@ driBOValidateUserList(struct _DriBufferList * list) buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); _glthread_LOCK_MUTEX(buf->mutex); if (buf->pool->validate) - BM_CKFATAL(buf->pool->validate(buf->pool, buf->private)); + BM_CKFATAL(buf->pool->validate(buf->pool, buf->private, &buf->mutex)); _glthread_UNLOCK_MUTEX(buf->mutex); curBuf = drmBOListNext(&list->driBuffers, curBuf); } diff --git a/src/mesa/drivers/dri/i915tex/ws_dri_bufpool.h b/src/mesa/drivers/dri/i915tex/ws_dri_bufpool.h index 0b8744febf..3a302e13d3 100644 --- a/src/mesa/drivers/dri/i915tex/ws_dri_bufpool.h +++ b/src/mesa/drivers/dri/i915tex/ws_dri_bufpool.h @@ -33,13 +33,15 @@ #define _PSB_BUFPOOL_H_ #include <xf86drm.h> +#include <glthread.h> struct _DriFenceObject; typedef struct _DriBufferPool { int fd; int (*map) (struct _DriBufferPool * pool, void *private, - unsigned flags, int hint, void **virtual); + unsigned flags, int hint, _glthread_Mutex *mutex, + void **virtual); int (*unmap) (struct _DriBufferPool * pool, void *private); int (*destroy) (struct _DriBufferPool * pool, void *private); unsigned long (*offset) (struct _DriBufferPool * pool, void *private); @@ -53,8 +55,8 @@ typedef struct _DriBufferPool int (*fence) (struct _DriBufferPool * pool, void *private, struct _DriFenceObject * fence); drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); - int (*validate) (struct _DriBufferPool * pool, void *private); - int (*waitIdle) (struct _DriBufferPool *pool, void *private, + int (*validate) (struct _DriBufferPool * pool, void *private, _glthread_Mutex *mutex); + int (*waitIdle) (struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, int lazy); int (*setStatus) (struct _DriBufferPool *pool, void *private, uint64_t flag_diff, uint64_t old_flags); diff --git a/src/mesa/drivers/dri/i915tex/ws_dri_drmpool.c b/src/mesa/drivers/dri/i915tex/ws_dri_drmpool.c index c45cb2142d..bb46b1d485 100644 --- a/src/mesa/drivers/dri/i915tex/ws_dri_drmpool.c +++ b/src/mesa/drivers/dri/i915tex/ws_dri_drmpool.c @@ -113,7 +113,7 @@ pool_unreference(struct _DriBufferPool *pool, void *private) static int pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, void **virtual) + int hint, _glthread_Mutex *mutex, void **virtual) { drmBO *buf = (drmBO *) private; int ret; @@ -202,7 +202,8 @@ pool_kernel(struct _DriBufferPool *pool, void *private) } static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy) +pool_waitIdle(struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, + int lazy) { drmBO *buf = (drmBO *) private; int ret; diff --git a/src/mesa/drivers/dri/i915tex/ws_dri_mallocpool.c b/src/mesa/drivers/dri/i915tex/ws_dri_mallocpool.c index 485fa43e9b..bf97d7e440 100644 --- a/src/mesa/drivers/dri/i915tex/ws_dri_mallocpool.c +++ b/src/mesa/drivers/dri/i915tex/ws_dri_mallocpool.c @@ -60,14 +60,15 @@ pool_destroy(struct _DriBufferPool *pool, void *private) } static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy) +pool_waitIdle(struct _DriBufferPool *pool, void *private, + _glthread_Mutex *mutex, int lazy) { return 0; } static int pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, void **virtual) + int hint, _glthread_Mutex *mutex, void **virtual) { *virtual = (void *)((unsigned long *)private + 2); return 0; @@ -126,13 +127,6 @@ pool_kernel(struct _DriBufferPool *pool, void *private) return NULL; } -static int -pool_validate(struct _DriBufferPool *pool, void *private) -{ - abort(); - return 0; -} - static void pool_takedown(struct _DriBufferPool *pool) { @@ -161,7 +155,7 @@ driMallocPoolInit(void) pool->create = &pool_create; pool->fence = &pool_fence; pool->kernel = &pool_kernel; - pool->validate = &pool_validate; + pool->validate = NULL; pool->waitIdle = &pool_waitIdle; pool->takeDown = &pool_takedown; return pool; diff --git a/src/mesa/drivers/dri/i915tex/ws_dri_slabpool.c b/src/mesa/drivers/dri/i915tex/ws_dri_slabpool.c index c92b62a052..30661ae30b 100644 --- a/src/mesa/drivers/dri/i915tex/ws_dri_slabpool.c +++ b/src/mesa/drivers/dri/i915tex/ws_dri_slabpool.c @@ -52,6 +52,8 @@ struct _DriSlabBuffer { uint32_t mapCount; uint32_t start; uint32_t fenceType; + int unFenced; + _glthread_Cond event; }; struct _DriKernelBO { @@ -349,6 +351,7 @@ driAllocSlab(struct _DriSlabSizeHeader *header) buf->start = i* header->bufSize; buf->mapCount = 0; buf->isSlabBuffer = 1; + _glthread_INIT_COND(buf->event); DRMLISTADDTAIL(&buf->head, &slab->freeBuffers); slab->numFree++; buf++; @@ -593,6 +596,8 @@ pool_destroy(struct _DriBufferPool *driPool, void *private) header = slab->header; _glthread_LOCK_MUTEX(header->mutex); + buf->unFenced = 0; + buf->mapCount = 0; if (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)) { DRMLISTADDTAIL(&buf->head, &header->delayedBuffers); @@ -606,12 +611,17 @@ pool_destroy(struct _DriBufferPool *driPool, void *private) } static int -pool_waitIdle(struct _DriBufferPool *driPool, void *private, int lazy) +pool_waitIdle(struct _DriBufferPool *driPool, void *private, + _glthread_Mutex *mutex, int lazy) { struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + while(buf->unFenced) + _glthread_COND_WAIT(buf->event, *mutex); + if (!buf->fence) return 0; + driFenceFinish(buf->fence, buf->fenceType, lazy); driFenceUnReference(&buf->fence); @@ -620,13 +630,13 @@ pool_waitIdle(struct _DriBufferPool *driPool, void *private, int lazy) static int pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, void **virtual) + int hint, _glthread_Mutex *mutex, void **virtual) { struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; int busy; if (buf->isSlabBuffer) - busy = buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType); + busy = buf->unFenced || (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)); else busy = buf->fence && !driFenceSignaled(buf->fence, buf->fenceType); @@ -634,8 +644,9 @@ pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, if (busy) { if (hint & DRM_BO_HINT_DONT_BLOCK) return -EBUSY; - else - (void) pool_waitIdle(pool, private, 0); + else { + (void) pool_waitIdle(pool, private, mutex, 0); + } } ++buf->mapCount; @@ -652,6 +663,9 @@ pool_unmap(struct _DriBufferPool *pool, void *private) struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; --buf->mapCount; + if (buf->mapCount == 0 && buf->isSlabBuffer) + _glthread_COND_BROADCAST(buf->event); + return 0; } @@ -720,6 +734,9 @@ pool_fence(struct _DriBufferPool *pool, void *private, buf->bo; buf->fenceType = bo->fenceFlags; + buf->unFenced = 0; + _glthread_COND_BROADCAST(buf->event); + return 0; } @@ -732,8 +749,18 @@ pool_kernel(struct _DriBufferPool *pool, void *private) } static int -pool_validate(struct _DriBufferPool *pool, void *private) +pool_validate(struct _DriBufferPool *pool, void *private, + _glthread_Mutex *mutex) { + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + if (!buf->isSlabBuffer) + return 0; + + while(buf->mapCount != 0) + _glthread_COND_WAIT(buf->event, *mutex); + + buf->unFenced = 1; return 0; } diff --git a/src/mesa/glapi/glthread.h b/src/mesa/glapi/glthread.h index a61086d0dc..77f2fe3ad8 100644 --- a/src/mesa/glapi/glthread.h +++ b/src/mesa/glapi/glthread.h @@ -116,9 +116,49 @@ typedef pthread_mutex_t _glthread_Mutex; #define _glthread_UNLOCK_MUTEX(name) \ (void) pthread_mutex_unlock(&(name)) -#endif /* PTHREADS */ +typedef pthread_cond_t _glthread_Cond; +#define _glthread_DECLARE_STATIC_COND(name) \ + static _glthread_Mutex name = PTHREAD_COND_INITIALIZER +#define _glthread_INIT_COND(cond) \ + pthread_cond_init(&(cond), NULL) + +#define _glthread_DESTROY_COND(name) \ + pthread_cond_destroy(&(name)) + +#define _glthread_COND_WAIT(cond, mutex) \ + pthread_cond_wait(&(cond), &(mutex)) + +#define _glthread_COND_SIGNAL(cond) \ + pthread_cond_signal(&(cond)) + +#define _glthread_COND_BROADCAST(cond) \ + pthread_cond_broadcast(&(cond)) + + +#else /* PTHREADS */ + +typedef unsigned int _glthread_Cond; +#define _glthread_DECLARE_STATIC_COND(name) \ + #warning Condition variables not implemented. + +#define _glthread_INIT_COND(cond) \ + abort(); + +#define _glthread_DESTROY_COND(name) \ + abort(); + +#define _glthread_COND_WAIT(cond, mutex) \ + abort(); + +#define _glthread_COND_SIGNAL(cond) \ + abort(); + +#define _glthread_COND_BROADCAST(cond) \ + abort(); + +#endif /* |