diff options
| author | Ben Skeggs <skeggsb@gmail.com> | 2007-12-23 16:18:00 +1100 | 
|---|---|---|
| committer | Ben Skeggs <skeggsb@gmail.com> | 2007-12-23 16:18:00 +1100 | 
| commit | 74757eb970984b0404c17255f3639d8a40591964 (patch) | |
| tree | b604c1aef50cdd61139fa695e6c2ef8ba6306dd0 /src | |
| parent | fa605cf661c09c5866cd9aa316b6a5ce9eb65c24 (diff) | |
nouveau: don't wait when deleting fences unless needed
Diffstat (limited to 'src')
| -rw-r--r-- | src/mesa/drivers/dri/nouveau_winsys/nouveau_fence.c | 41 | 
1 files changed, 35 insertions, 6 deletions
| diff --git a/src/mesa/drivers/dri/nouveau_winsys/nouveau_fence.c b/src/mesa/drivers/dri/nouveau_winsys/nouveau_fence.c index 3b35a11bcb..53037d1682 100644 --- a/src/mesa/drivers/dri/nouveau_winsys/nouveau_fence.c +++ b/src/mesa/drivers/dri/nouveau_winsys/nouveau_fence.c @@ -22,6 +22,7 @@  #include <stdlib.h>  #include <errno.h> +#include <assert.h>  #include "nouveau_drmif.h"  #include "nouveau_dma.h" @@ -59,6 +60,28 @@ nouveau_fence_ref(struct nouveau_fence *ref, struct nouveau_fence **fence)  	return 0;  } +static void +nouveau_fence_del_unsignalled(struct nouveau_fence *fence) +{ +	struct nouveau_channel_priv *nvchan = nouveau_channel(fence->channel); +	struct nouveau_fence *le; + +	if (nvchan->fence_head == fence) { +		nvchan->fence_head = nouveau_fence(fence)->next; +		if (nvchan->fence_head == NULL) +			nvchan->fence_tail = NULL; +		return; +	} + +	le = nvchan->fence_head; +	while (le && nouveau_fence(le)->next != fence) +		le = nouveau_fence(le)->next; +	assert(le && nouveau_fence(le)->next == fence); +	nouveau_fence(le)->next = nouveau_fence(fence)->next; +	if (nvchan->fence_tail == fence) +		nvchan->fence_tail = le; +} +  void  nouveau_fence_del(struct nouveau_fence **fence)  { @@ -69,11 +92,19 @@ nouveau_fence_del(struct nouveau_fence **fence)  	nvfence = nouveau_fence(*fence);  	*fence = NULL; -	if (--nvfence->refcount <= 0) { -		if (nvfence->emitted && !nvfence->signalled) +	if (--nvfence->refcount) +		return; + +	if (nvfence->emitted && !nvfence->signalled) { +		if (nvfence->signal_cb) { +			nvfence->refcount++;  			nouveau_fence_wait((void *)&nvfence); -		free(nvfence); +			return; +		} + +		nouveau_fence_del_unsignalled(&nvfence->base);  	} +	free(nvfence);  }  int @@ -139,9 +170,7 @@ nouveau_fence_flush(struct nouveau_channel *chan)  			break;  		} -		nvchan->fence_head = nvfence->next; -		if (nvchan->fence_head == NULL) -			nvchan->fence_tail = NULL; +		nouveau_fence_del_unsignalled(&nvfence->base);  		nvfence->signalled = 1;  		while (nvfence->signal_cb) { | 
