diff options
author | Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> | 2008-04-25 15:08:13 +0200 |
---|---|---|
committer | Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> | 2008-04-25 15:08:13 +0200 |
commit | 1f8de43ffb9b2fb7011af639e79c2cf46d9e910f (patch) | |
tree | df83417585751d5c1aaf445434dbb7ab01bf768d | |
parent | 24a7f0a27bf9785890f8d0dff90853967a6a9b7b (diff) |
Update to latest ws_dri code.
-rw-r--r-- | src/mesa/drivers/dri/i915tex/ws_dri_bufmgr.c | 134 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915tex/ws_dri_bufmgr.h | 8 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915tex/ws_dri_drmpool.c | 21 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915tex/ws_dri_mallocpool.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915tex/ws_dri_slabpool.c | 109 |
5 files changed, 187 insertions, 87 deletions
diff --git a/src/mesa/drivers/dri/i915tex/ws_dri_bufmgr.c b/src/mesa/drivers/dri/i915tex/ws_dri_bufmgr.c index 52f29004b4..6f39a5d020 100644 --- a/src/mesa/drivers/dri/i915tex/ws_dri_bufmgr.c +++ b/src/mesa/drivers/dri/i915tex/ws_dri_bufmgr.c @@ -53,6 +53,7 @@ _glthread_DECLARE_STATIC_MUTEX(bmMutex); _glthread_DECLARE_STATIC_COND(bmCond); static int kernelReaders = 0; +static int kernelLocked = 0; static drmBO *drmBOListBuf(void *iterator) { @@ -83,11 +84,13 @@ static void *drmBOListNext(drmBOList *list, void *iterator) } static drmBONode *drmAddListItem(drmBOList *list, drmBO *item, + uint32_t hash, uint64_t arg0, uint64_t arg1) { drmBONode *node; drmMMListHead *l; + drmMMListHead *hashHead; l = list->free.next; if (l == &list->free) { @@ -104,29 +107,57 @@ static drmBONode *drmAddListItem(drmBOList *list, drmBO *item, node->buf = item; node->arg0 = arg0; node->arg1 = arg1; - DRMLISTADD(&node->head, &list->list); + node->listItem = list->numOnList; + DRMLISTADDTAIL(&node->head, &list->list); list->numOnList++; + hashHead = list->hashTable + hash; + DRMLISTADDTAIL(&node->hashHead, hashHead); + return node; } +static uint32_t driHashFunc(uint8_t *key, uint32_t len) +{ + uint32_t hash, i; + + return 0; + for (hash = 0, i = 0; i<len; ++i) { + hash += *key++; + hash += (hash << 10); + hash ^= (hash >> 6); + } + + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + + return hash & DRI_LIST_HASHTAB_MASK; +} + + static int drmAddValidateItem(drmBOList *list, drmBO *buf, uint64_t flags, uint64_t mask, int *newItem) { drmBONode *node, *cur; drmMMListHead *l; + drmMMListHead *hashHead; + uint32_t hash; *newItem = 0; cur = NULL; - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); + hash = driHashFunc((uint8_t *) buf, (sizeof(buf))); + hashHead = list->hashTable + hash; + + for (l = hashHead->next; l != hashHead; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, hashHead); if (node->buf == buf) { cur = node; break; } } if (!cur) { - cur = drmAddListItem(list, buf, flags, mask); + cur = drmAddListItem(list, buf, hash, flags, mask); if (!cur) { return -ENOMEM; } @@ -162,6 +193,7 @@ static void drmBOFreeList(drmBOList *list) while(l != &list->list) { DRMLISTDEL(l); node = DRMLISTENTRY(drmBONode, l, head); + DRMLISTDEL(&node->hashHead); free(node); l = list->list.next; list->numCurrent--; @@ -208,6 +240,12 @@ static int drmAdjustListNodes(drmBOList *list) static int drmBOCreateList(int numTarget, drmBOList *list) { + int + i; + + for (i=0; i<DRI_LIST_HASHTAB_SIZE; ++i) + DRMINITLISTHEAD(&list->hashTable[i]); + DRMINITLISTHEAD(&list->list); DRMINITLISTHEAD(&list->free); list->numTarget = numTarget; @@ -219,6 +257,7 @@ static int drmBOCreateList(int numTarget, drmBOList *list) static int drmBOResetList(drmBOList *list) { drmMMListHead *l; + drmBONode *node; int ret; ret = drmAdjustListNodes(list); @@ -228,6 +267,8 @@ static int drmBOResetList(drmBOList *list) l = list->list.next; while (l != &list->list) { DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + DRMLISTDEL(&node->hashHead); DRMLISTADD(l, &list->free); list->numOnList--; l = list->list.next; @@ -240,25 +281,30 @@ void driWriteLockKernelBO(void) _glthread_LOCK_MUTEX(bmMutex); while(kernelReaders != 0) _glthread_COND_WAIT(bmCond, bmMutex); + kernelLocked = 1; } void driWriteUnlockKernelBO(void) { + kernelLocked = 0; _glthread_UNLOCK_MUTEX(bmMutex); } void driReadLockKernelBO(void) { _glthread_LOCK_MUTEX(bmMutex); - kernelReaders++; + if (kernelReaders++ == 0) + kernelLocked = 1; _glthread_UNLOCK_MUTEX(bmMutex); } void driReadUnlockKernelBO(void) { _glthread_LOCK_MUTEX(bmMutex); - if (--kernelReaders == 0) + if (--kernelReaders == 0) { + kernelLocked = 0; _glthread_COND_BROADCAST(bmCond); + } _glthread_UNLOCK_MUTEX(bmMutex); } @@ -309,18 +355,37 @@ driBOKernel(struct _DriBufferObject *buf) { drmBO *ret; - driReadLockKernelBO(); _glthread_LOCK_MUTEX(buf->mutex); assert(buf->private != NULL); + assert(kernelLocked == 1); ret = buf->pool->kernel(buf->pool, buf->private); if (!ret) BM_CKFATAL(-EINVAL); _glthread_UNLOCK_MUTEX(buf->mutex); - driReadUnlockKernelBO(); return ret; } +extern uint32_t driBOHandle(struct _DriBufferObject *buf) +{ + drmBO *bo; + + /* + * Doesn't need the kernelBO lock since the + * kernelBO handle is always constant. + */ + + _glthread_LOCK_MUTEX(buf->mutex); + assert(buf->private != NULL); + bo = buf->pool->kernel(buf->pool, buf->private); + if (!bo) + BM_CKFATAL(-EINVAL); + _glthread_UNLOCK_MUTEX(buf->mutex); + + return bo->handle; +} + + void driBOWaitIdle(struct _DriBufferObject *buf, int lazy) { @@ -367,6 +432,7 @@ driBOOffset(struct _DriBufferObject *buf) assert(buf->private != NULL); _glthread_LOCK_MUTEX(buf->mutex); + assert(kernelLocked == 1); ret = buf->pool->offset(buf->pool, buf->private); _glthread_UNLOCK_MUTEX(buf->mutex); return ret; @@ -392,11 +458,10 @@ driBOFlags(struct _DriBufferObject *buf) assert(buf->private != NULL); - driReadLockKernelBO(); _glthread_LOCK_MUTEX(buf->mutex); + assert(kernelLocked == 1); ret = buf->pool->flags(buf->pool, buf->private); _glthread_UNLOCK_MUTEX(buf->mutex); - driReadUnlockKernelBO(); return ret; } @@ -506,11 +571,17 @@ driBOData(struct _DriBufferObject *buf, buf->alignment); if (newBuf) { buf->pool->destroy(buf->pool, buf->private); + buf->pool = newPool; buf->private = newBuf; } - retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); + if (!buf->private) + retval = -ENOMEM; + + if (retval == 0) + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); + } else { uint64_t flag_diff = flags ^ buf->flags; @@ -520,22 +591,28 @@ driBOData(struct _DriBufferObject *buf, if (flag_diff){ assert(pool->setStatus != NULL); - BM_CKFATAL(pool->unmap(pool, buf->private)); - BM_CKFATAL(pool->setStatus(pool, buf->private, flag_diff, - buf->flags)); - if (!data) + (void) pool->unmap(pool, buf->private); + retval = pool->setStatus(pool, buf->private, flag_diff, + buf->flags); + if (retval) goto out; + + if (!data) { + buf->flags = flags; + goto out; + } retval = pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); - } + } } if (retval == 0) { if (data) memcpy(virtual, data, size); - BM_CKFATAL(pool->unmap(pool, buf->private)); + (void) pool->unmap(pool, buf->private); + buf->flags = flags; } out: @@ -695,10 +772,11 @@ driBOFreeList(struct _DriBufferList * list) static drmBONode * driAddListItem(drmBOList * list, drmBO * item, - uint64_t arg0, uint64_t arg1) + uint32_t hash, uint64_t arg0, uint64_t arg1) { drmBONode *node; drmMMListHead *l; + drmMMListHead *hashHead; l = list->free.next; if (l == &list->free) { @@ -715,7 +793,10 @@ driAddListItem(drmBOList * list, drmBO * item, node->buf = item; node->arg0 = arg0; node->arg1 = arg1; + node->listItem = list->numOnList; DRMLISTADDTAIL(&node->head, &list->list); + hashHead = list->hashTable + hash; + DRMLISTADDTAIL(&node->hashHead, hashHead); list->numOnList++; return node; } @@ -732,20 +813,23 @@ driAddValidateItem(drmBOList * list, drmBO * buf, uint64_t flags, { drmBONode *node, *cur; drmMMListHead *l; - int count = 0; + drmMMListHead *hashHead; + uint32_t hash; cur = NULL; - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); + hash = driHashFunc((uint8_t *) buf, (sizeof(buf))); + hashHead = list->hashTable + hash; + + for (l = hashHead->next; l != hashHead; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, hashHead); if (node->buf == buf) { cur = node; break; } - count++; } if (!cur) { - cur = driAddListItem(list, buf, flags, mask); + cur = driAddListItem(list, buf, hash, flags, mask); if (!cur) return -ENOMEM; @@ -767,7 +851,7 @@ driAddValidateItem(drmBOList * list, drmBO * buf, uint64_t flags, return -EINVAL; } } - *itemLoc = count; + *itemLoc = cur->listItem; *pnode = cur; return 0; } diff --git a/src/mesa/drivers/dri/i915tex/ws_dri_bufmgr.h b/src/mesa/drivers/dri/i915tex/ws_dri_bufmgr.h index 0941c11cea..fdd2a3f8ca 100644 --- a/src/mesa/drivers/dri/i915tex/ws_dri_bufmgr.h +++ b/src/mesa/drivers/dri/i915tex/ws_dri_bufmgr.h @@ -36,9 +36,15 @@ #include "i915_drm.h" #include "ws_dri_fencemgr.h" +#define DRI_LIST_HASHTAB_SIZE 256 +#define DRI_LIST_HASHTAB_MASK 0xff + typedef struct _drmBONode { + uint32_t hash; drmMMListHead head; + drmMMListHead hashHead; + int listItem; drmBO *buf; struct drm_i915_op_arg bo_arg; uint64_t arg0; @@ -51,6 +57,7 @@ typedef struct _drmBOList { unsigned numOnList; drmMMListHead list; drmMMListHead free; + drmMMListHead hashTable[DRI_LIST_HASHTAB_SIZE]; } drmBOList; @@ -64,6 +71,7 @@ struct _DriBufferList; * uses. */ +extern uint32_t driBOHandle(struct _DriBufferObject *buf); extern drmBO *driBOKernel(struct _DriBufferObject *buf); extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint); diff --git a/src/mesa/drivers/dri/i915tex/ws_dri_drmpool.c b/src/mesa/drivers/dri/i915tex/ws_dri_drmpool.c index bb46b1d485..d8f8cfd624 100644 --- a/src/mesa/drivers/dri/i915tex/ws_dri_drmpool.c +++ b/src/mesa/drivers/dri/i915tex/ws_dri_drmpool.c @@ -92,10 +92,8 @@ pool_destroy(struct _DriBufferPool *pool, void *private) { int ret; drmBO *buf = (drmBO *) private; - driReadLockKernelBO(); ret = drmBOUnreference(pool->fd, buf); free(buf); - driReadUnlockKernelBO(); return ret; } @@ -104,10 +102,8 @@ pool_unreference(struct _DriBufferPool *pool, void *private) { int ret; drmBO *buf = (drmBO *) private; - driReadLockKernelBO(); ret = drmBOUnreference(pool->fd, buf); free(buf); - driReadUnlockKernelBO(); return ret; } @@ -118,9 +114,7 @@ pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, drmBO *buf = (drmBO *) private; int ret; - driReadLockKernelBO(); ret = drmBOMap(pool->fd, buf, flags, hint, virtual); - driReadUnlockKernelBO(); return ret; } @@ -130,9 +124,7 @@ pool_unmap(struct _DriBufferPool *pool, void *private) drmBO *buf = (drmBO *) private; int ret; - driReadLockKernelBO(); ret = drmBOUnmap(pool->fd, buf); - driReadUnlockKernelBO(); return ret; } @@ -143,10 +135,8 @@ pool_offset(struct _DriBufferPool *pool, void *private) drmBO *buf = (drmBO *) private; unsigned long offset; - driReadLockKernelBO(); assert(buf->flags & DRM_BO_FLAG_NO_MOVE); offset = buf->offset; - driReadUnlockKernelBO(); return buf->offset; } @@ -163,9 +153,7 @@ pool_flags(struct _DriBufferPool *pool, void *private) drmBO *buf = (drmBO *) private; uint64_t flags; - driReadLockKernelBO(); flags = buf->flags; - driReadUnlockKernelBO(); return flags; } @@ -177,9 +165,7 @@ pool_size(struct _DriBufferPool *pool, void *private) drmBO *buf = (drmBO *) private; unsigned long size; - driReadLockKernelBO(); size = buf->size; - driReadUnlockKernelBO(); return buf->size; } @@ -208,9 +194,7 @@ pool_waitIdle(struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex drmBO *buf = (drmBO *) private; int ret; - driReadLockKernelBO(); ret = drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); - driReadUnlockKernelBO(); return ret; } @@ -230,10 +214,8 @@ pool_setStatus(struct _DriBufferPool *pool, void *private, uint64_t new_flags = old_flags ^ flag_diff; int ret; - driReadLockKernelBO(); ret = drmBOSetStatus(pool->fd, buf, new_flags, flag_diff, 0, 0, 0); - driReadUnlockKernelBO(); return ret; } @@ -242,7 +224,7 @@ driDRMPoolInit(int fd) { struct _DriBufferPool *pool; - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + pool = (struct _DriBufferPool *) calloc(1, sizeof(*pool)); if (!pool) return NULL; @@ -263,6 +245,7 @@ driDRMPoolInit(int fd) pool->takeDown = &pool_takedown; pool->reference = &pool_reference; pool->unreference = &pool_unreference; + pool->setStatus = &pool_setStatus; pool->data = NULL; return pool; } diff --git a/src/mesa/drivers/dri/i915tex/ws_dri_mallocpool.c b/src/mesa/drivers/dri/i915tex/ws_dri_mallocpool.c index bf97d7e440..bf91bc72b9 100644 --- a/src/mesa/drivers/dri/i915tex/ws_dri_mallocpool.c +++ b/src/mesa/drivers/dri/i915tex/ws_dri_mallocpool.c @@ -139,7 +139,7 @@ driMallocPoolInit(void) { struct _DriBufferPool *pool; - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + pool = (struct _DriBufferPool *) calloc(1, sizeof(*pool)); if (!pool) return NULL; diff --git a/src/mesa/drivers/dri/i915tex/ws_dri_slabpool.c b/src/mesa/drivers/dri/i915tex/ws_dri_slabpool.c index 30661ae30b..b411305e7e 100644 --- a/src/mesa/drivers/dri/i915tex/ws_dri_slabpool.c +++ b/src/mesa/drivers/dri/i915tex/ws_dri_slabpool.c @@ -227,6 +227,7 @@ driAllocKernelBO(struct _DriSlabSizeHeader *header) drmMMListHead *list, *next, *head; uint32_t size = header->bufSize * slabPool->desiredNumBuffers; struct _DriKernelBO *kbo; + struct _DriKernelBO *kboTmp; int ret; /* @@ -248,27 +249,36 @@ driAllocKernelBO(struct _DriSlabSizeHeader *header) list != head; list = next, next = list->next) { - kbo = DRMLISTENTRY(struct _DriKernelBO, list, head); + kboTmp = DRMLISTENTRY(struct _DriKernelBO, list, head); - if ((kbo->bo.size == size) && + if ((kboTmp->bo.size == size) && (slabPool->pageAlignment == 0 || - (kbo->pageAlignment % slabPool->pageAlignment) == 0)) { + (kboTmp->pageAlignment % slabPool->pageAlignment) == 0)) { + + if (!kbo) + kbo = kboTmp; - DRMLISTDELINIT(&kbo->head); - DRMLISTDELINIT(&kbo->timeoutHead); - break; - } + if ((kbo->bo.proposedFlags ^ slabPool->proposedFlags) == 0) + break; - kbo = NULL; + } + } + + if (kbo) { + DRMLISTDELINIT(&kbo->head); + DRMLISTDELINIT(&kbo->timeoutHead); } _glthread_UNLOCK_MUTEX(fMan->mutex); if (kbo) { + uint64_t new_mask = kbo->bo.proposedFlags ^ slabPool->proposedFlags; + ret = 0; - ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, - (slabPool->proposedFlags ^ kbo->bo.flags), - DRM_BO_HINT_DONT_FENCE, 0, 0); + if (new_mask) { + ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, + new_mask, DRM_BO_HINT_DONT_FENCE, 0, 0); + } if (ret == 0) return kbo; @@ -284,7 +294,6 @@ driAllocKernelBO(struct _DriSlabSizeHeader *header) kbo->fd = slabPool->fd; DRMINITLISTHEAD(&kbo->head); DRMINITLISTHEAD(&kbo->timeoutHead); - ret = drmBOCreate(kbo->fd, size, slabPool->pageAlignment, NULL, slabPool->proposedFlags, DRM_BO_HINT_DONT_FENCE, &kbo->bo); @@ -417,47 +426,61 @@ driSlabFreeBufferLocked(struct _DriSlabBuffer *buf) static void driSlabCheckFreeLocked(struct _DriSlabSizeHeader *header, int wait) { - drmMMListHead *list, *prev; + drmMMListHead *list, *prev, *first; struct _DriSlabBuffer *buf; struct _DriSlab *slab; - - int signaled = 0; + int firstWasSignaled = 1; + int signaled; int i; int ret; - list = header->delayedBuffers.next; - - /* Only examine the oldest 1/3 of delayed buffers: + /* + * Rerun the freeing test if the youngest tested buffer + * was signaled, since there might be more idle buffers + * in the delay list. */ - if (header->numDelayed > 3) { - for (i = 0; i < header->numDelayed; i += 3) { - list = list->next; - } - } - prev = list->prev; - for (; list != &header->delayedBuffers; list = prev, prev = list->prev) { - buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); - slab = buf->parent; - - if (!signaled) { - if (wait) { - ret = driFenceFinish(buf->fence, buf->fenceType, 0); - if (ret) - break; - signaled = 1; - } else { - signaled = driFenceSignaled(buf->fence, buf->fenceType); + while (firstWasSignaled) { + firstWasSignaled = 0; + signaled = 0; + first = header->delayedBuffers.next; + + /* Only examine the oldest 1/3 of delayed buffers: + */ + if (header->numDelayed > 3) { + for (i = 0; i < header->numDelayed; i += 3) { + first = first->next; } - if (signaled) { + } + + for (list = first, prev = list->prev; + list != &header->delayedBuffers; + list = prev, prev = list->prev) { + buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); + slab = buf->parent; + + if (!signaled) { + if (wait) { + ret = driFenceFinish(buf->fence, buf->fenceType, 0); + if (ret) + break; + signaled = 1; + wait = 0; + } else { + signaled = driFenceSignaled(buf->fence, buf->fenceType); + } + if (signaled) { + if (list == first) + firstWasSignaled = 1; + driFenceUnReference(&buf->fence); + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { driFenceUnReference(&buf->fence); header->numDelayed--; driSlabFreeBufferLocked(buf); } - } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { - driFenceUnReference(&buf->fence); - header->numDelayed--; - driSlabFreeBufferLocked(buf); } } } @@ -480,8 +503,8 @@ driSlabAllocBuffer(struct _DriSlabSizeHeader *header) _glthread_UNLOCK_MUTEX(header->mutex); if (count != DRI_SLABPOOL_ALLOC_RETRIES) usleep(1); - (void) driAllocSlab(header); _glthread_LOCK_MUTEX(header->mutex); + (void) driAllocSlab(header); count--; } @@ -603,6 +626,8 @@ pool_destroy(struct _DriBufferPool *driPool, void *private) DRMLISTADDTAIL(&buf->head, &header->delayedBuffers); header->numDelayed++; } else { + if (buf->fence) + driFenceUnReference(&buf->fence); driSlabFreeBufferLocked(buf); } |