nouveau: allow multiple simultaneous maps of a pipe_transfer
authorBen Skeggs <bskeggs@redhat.com>
Wed, 7 Apr 2010 05:41:17 +0000 (15:41 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 7 Apr 2010 05:51:13 +0000 (15:51 +1000)
I'm not entirely convinced we want this behaviour (the underlying nouveau_bo
doesn't support it either), but since certain parts of the mesa state
tracker appear to require it lets make it work for now.

src/gallium/drivers/nv50/nv50_transfer.c

index 9eb223eca65583415652eb8e478cd40fcdc72758..6d16c1354bb1a0bad602b64369bb9032a0fcd7c1 100644 (file)
@@ -9,6 +9,7 @@
 struct nv50_transfer {
        struct pipe_transfer base;
        struct nouveau_bo *bo;
+       int map_refcnt;
        unsigned level_offset;
        unsigned level_tiling;
        int level_pitch;
@@ -225,14 +226,19 @@ nv50_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx)
        unsigned flags = 0;
        int ret;
 
+       if (tx->map_refcnt++)
+               return tx->bo->map;
+
        if (ptx->usage & PIPE_TRANSFER_WRITE)
                flags |= NOUVEAU_BO_WR;
        if (ptx->usage & PIPE_TRANSFER_READ)
                flags |= NOUVEAU_BO_RD;
 
        ret = nouveau_bo_map(tx->bo, flags);
-       if (ret)
+       if (ret) {
+               tx->map_refcnt = 0;
                return NULL;
+       }
        return tx->bo->map;
 }
 
@@ -241,6 +247,8 @@ nv50_transfer_unmap(struct pipe_context *pcontext, struct pipe_transfer *ptx)
 {
        struct nv50_transfer *tx = (struct nv50_transfer *)ptx;
 
+       if (--tx->map_refcnt)
+               return;
        nouveau_bo_unmap(tx->bo);
 }