]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/libdrm.git/commitdiff
nouveau: add reloc refcnt to pending bo list
authorBen Skeggs <bskeggs@redhat.com>
Tue, 27 Oct 2009 04:32:40 +0000 (14:32 +1000)
committerBen Skeggs <skeggsb@beleth.(none)>
Wed, 4 Nov 2009 04:58:19 +0000 (14:58 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
libdrm/nouveau/nouveau_bo.c
libdrm/nouveau/nouveau_private.h
libdrm/nouveau/nouveau_pushbuf.c

index b7e6d867f179370512f9fce603d9fa5a51a19cf3..85fc14f6b82e9976f948e7f29a0a55a5384ef9cc 100644 (file)
@@ -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;
index 9ce87fb2024aab70f57ebd100ae85d08c294e6be..743c831403410aeadd725a96ff17d6170940f8e8 100644 (file)
@@ -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 */
index d434a5fcb2e8916337386fe848d4cfd68c5ce9ac..af181b2eb9b098593d8b0070fc9cca20690899ef 100644 (file)
@@ -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;