summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2008-04-25 15:08:13 +0200
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2008-04-25 15:08:13 +0200
commit1f8de43ffb9b2fb7011af639e79c2cf46d9e910f (patch)
treedf83417585751d5c1aaf445434dbb7ab01bf768d
parent24a7f0a27bf9785890f8d0dff90853967a6a9b7b (diff)
Update to latest ws_dri code.
-rw-r--r--src/mesa/drivers/dri/i915tex/ws_dri_bufmgr.c134
-rw-r--r--src/mesa/drivers/dri/i915tex/ws_dri_bufmgr.h8
-rw-r--r--src/mesa/drivers/dri/i915tex/ws_dri_drmpool.c21
-rw-r--r--src/mesa/drivers/dri/i915tex/ws_dri_mallocpool.c2
-rw-r--r--src/mesa/drivers/dri/i915tex/ws_dri_slabpool.c109
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);
}