diff options
Diffstat (limited to 'libdrm/nouveau')
-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; |