summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2008-03-30 17:34:03 +0200
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2008-03-30 17:34:03 +0200
commit6b78eed962c65ff93b51ee1677ae3f73c7a18589 (patch)
tree11faca5964e5e15357497b3b03b862bd0952f03d
parent6c80f5876b0b00e6ba958e8aff9e31079cbcd681 (diff)
Add proper waiting for unmap / fencing.
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_batchbuffer.c1
-rw-r--r--src/mesa/drivers/dri/i915tex/ws_dri_bufmgr.c20
-rw-r--r--src/mesa/drivers/dri/i915tex/ws_dri_bufpool.h8
-rw-r--r--src/mesa/drivers/dri/i915tex/ws_dri_drmpool.c5
-rw-r--r--src/mesa/drivers/dri/i915tex/ws_dri_mallocpool.c14
-rw-r--r--src/mesa/drivers/dri/i915tex/ws_dri_slabpool.c39
-rw-r--r--src/mesa/glapi/glthread.h42
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
/*