diff options
| author | Ben Skeggs <bskeggs@redhat.com> | 2009-10-27 14:32:40 +1000 | 
|---|---|---|
| committer | Ben Skeggs <skeggsb@beleth.(none)> | 2009-11-04 14:58:19 +1000 | 
| commit | a8bdf0e00c0653fd343fd7fd64b5f2e8437bb130 (patch) | |
| tree | 43c6b49c4519126f0191df1d9596969d70ac2f3a /libdrm | |
| parent | 63910f8aa624be5f2eaa78e08a318d388a22f829 (diff) | |
nouveau: add reloc refcnt to pending bo list
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'libdrm')
| -rw-r--r-- | libdrm/nouveau/nouveau_bo.c | 1 | ||||
| -rw-r--r-- | libdrm/nouveau/nouveau_private.h | 1 | ||||
| -rw-r--r-- | libdrm/nouveau/nouveau_pushbuf.c | 24 | 
3 files changed, 19 insertions, 7 deletions
| diff --git a/libdrm/nouveau/nouveau_bo.c b/libdrm/nouveau/nouveau_bo.c index b7e6d867..85fc14f6 100644 --- a/libdrm/nouveau/nouveau_bo.c +++ b/libdrm/nouveau/nouveau_bo.c @@ -607,6 +607,7 @@ nouveau_bo_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo)  	pbbo = nvpb->buffers + nvpb->nr_buffers++;  	nvbo->pending = pbbo;  	nvbo->pending_channel = chan; +	nvbo->pending_refcnt = 0;  	nouveau_bo_ref(bo, &ref);  	pbbo->user_priv = (uint64_t)(unsigned long)ref; diff --git a/libdrm/nouveau/nouveau_private.h b/libdrm/nouveau/nouveau_private.h index 9ce87fb2..743c8314 100644 --- a/libdrm/nouveau/nouveau_private.h +++ b/libdrm/nouveau/nouveau_private.h @@ -99,6 +99,7 @@ struct nouveau_bo_priv {  	/* Tracking */  	struct drm_nouveau_gem_pushbuf_bo *pending;  	struct nouveau_channel *pending_channel; +	int pending_refcnt;  	int write_marker;  	/* Userspace object */ diff --git a/libdrm/nouveau/nouveau_pushbuf.c b/libdrm/nouveau/nouveau_pushbuf.c index d434a5fc..af181b2e 100644 --- a/libdrm/nouveau/nouveau_pushbuf.c +++ b/libdrm/nouveau/nouveau_pushbuf.c @@ -60,6 +60,7 @@ nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr,  			   uint32_t flags, uint32_t vor, uint32_t tor)  {  	struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); +	struct nouveau_bo_priv *nvbo = nouveau_bo(bo);  	struct drm_nouveau_gem_pushbuf_reloc *r;  	struct drm_nouveau_gem_pushbuf_bo *pbbo;  	uint32_t domains = 0; @@ -70,7 +71,7 @@ nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr,  		return -ENOMEM;  	} -	if (nouveau_bo(bo)->user && (flags & NOUVEAU_BO_WR)) { +	if (nvbo->user && (flags & NOUVEAU_BO_WR)) {  		fprintf(stderr, "write to user buffer!!\n");  		return -EINVAL;  	} @@ -82,6 +83,8 @@ nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr,  		return -ENOMEM;  	} +	nvbo->pending_refcnt++; +  	if (flags & NOUVEAU_BO_VRAM)  		domains |= NOUVEAU_GEM_DOMAIN_VRAM;  	if (flags & NOUVEAU_BO_GART) @@ -95,7 +98,7 @@ nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr,  	}  	if (flags & NOUVEAU_BO_WR) {  		pbbo->write_domains |= domains; -		nouveau_bo(bo)->write_marker = 1; +		nvbo->write_marker = 1;  	}  	r = nvpb->relocs + nvpb->nr_relocs++; @@ -322,18 +325,25 @@ restart_push:  	/* Update presumed offset/domain for any buffers that moved.  	 * Dereference all buffers on validate list  	 */ -	for (i = 0; i < nvpb->nr_buffers; i++) { -		struct drm_nouveau_gem_pushbuf_bo *pbbo = &nvpb->buffers[i]; +	for (i = 0; i < nvpb->nr_relocs; i++) { +		struct drm_nouveau_gem_pushbuf_reloc *r = &nvpb->relocs[i]; +		struct drm_nouveau_gem_pushbuf_bo *pbbo = +			&nvpb->buffers[r->bo_index];  		struct nouveau_bo *bo = (void *)(unsigned long)pbbo->user_priv; +		struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + +		if (--nvbo->pending_refcnt) +			continue;  		if (pbbo->presumed_ok == 0) { -			nouveau_bo(bo)->domain = pbbo->presumed_domain; -			nouveau_bo(bo)->offset = pbbo->presumed_offset; +			nvbo->domain = pbbo->presumed_domain; +			nvbo->offset = pbbo->presumed_offset;  		} -		nouveau_bo(bo)->pending = NULL; +		nvbo->pending = NULL;  		nouveau_bo_ref(NULL, &bo);  	} +  	nvpb->nr_buffers = 0;  	nvpb->nr_relocs = 0; | 
