nvc0: fix user vertex buffer updates
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Tue, 15 Feb 2011 18:12:41 +0000 (19:12 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Wed, 16 Feb 2011 14:45:30 +0000 (15:45 +0100)
src/gallium/drivers/nvc0/nvc0_buffer.c
src/gallium/drivers/nvc0/nvc0_resource.h
src/gallium/drivers/nvc0/nvc0_screen.h
src/gallium/drivers/nvc0/nvc0_vbo.c

index ea3e642a4483cfedf3572de0ae478c008ed33650..f16671ac7ffad28fe695f01404f1b2f8300e2366 100644 (file)
@@ -59,15 +59,23 @@ release_allocation(struct nvc0_mm_allocation **mm, struct nvc0_fence *fence)
    (*mm) = NULL;
 }
 
-static INLINE boolean
-nvc0_buffer_reallocate(struct nvc0_screen *screen, struct nvc0_resource *buf,
-                       unsigned domain)
+INLINE void
+nvc0_buffer_release_gpu_storage(struct nvc0_resource *buf)
 {
    nouveau_bo_ref(NULL, &buf->bo);
 
    if (buf->mm)
       release_allocation(&buf->mm, buf->fence);
 
+   buf->domain = 0;
+}
+
+static INLINE boolean
+nvc0_buffer_reallocate(struct nvc0_screen *screen, struct nvc0_resource *buf,
+                       unsigned domain)
+{
+   nvc0_buffer_release_gpu_storage(buf);
+
    return nvc0_buffer_allocate(screen, buf, domain);
 }
 
@@ -77,10 +85,7 @@ nvc0_buffer_destroy(struct pipe_screen *pscreen,
 {
    struct nvc0_resource *res = nvc0_resource(presource);
 
-   nouveau_bo_ref(NULL, &res->bo);
-
-   if (res->mm)
-      release_allocation(&res->mm, res->fence);
+   nvc0_buffer_release_gpu_storage(res);
 
    if (res->data && !(res->status & NVC0_BUFFER_STATUS_USER_MEMORY))
       FREE(res->data);
index 17e79642a6d3003f5d6982065061cc2a77018c73..709e6157f55e00061e9b565554d8348b5dedb971 100644 (file)
@@ -51,6 +51,9 @@ struct nvc0_resource {
    struct nvc0_mm_allocation *mm;
 };
 
+void
+nvc0_buffer_release_gpu_storage(struct nvc0_resource *);
+
 boolean
 nvc0_buffer_download(struct nvc0_context *, struct nvc0_resource *,
                      unsigned start, unsigned size);
index 1fac142e2be588888f5db7ab2ba5a604570f7f31..3b676fd21a1f9df8ff8a16228d93d35f8ecb0d04 100644 (file)
@@ -128,9 +128,11 @@ nvc0_resource_validate(struct nvc0_resource *res, uint32_t flags)
 {
    struct nvc0_screen *screen = nvc0_screen(res->base.screen);
 
-   nouveau_bo_validate(screen->base.channel, res->bo, flags);
+   if (likely(res->bo)) {
+      nouveau_bo_validate(screen->base.channel, res->bo, flags);
 
-   nvc0_resource_fence(res, flags);
+      nvc0_resource_fence(res, flags);
+   }
 }
 
 
index 80e05823759796ca9abb00457cf6846ec0eae9fa..fb135725c3f9034e33769e5f98f7273015d0fad2 100644 (file)
@@ -171,12 +171,15 @@ nvc0_prevalidate_vbufs(struct nvc0_context *nvc0)
 
    nvc0->vbo_fifo = nvc0->vbo_user = 0;
 
+   nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_VERTEX);
+
    for (i = 0; i < nvc0->num_vtxbufs; ++i) {
       vb = &nvc0->vtxbuf[i];
       if (!vb->stride)
          continue;
       buf = nvc0_resource(vb->buffer);
 
+      /* NOTE: user buffers with temporary storage count as mapped by GPU */
       if (!nvc0_resource_mapped_by_gpu(vb->buffer)) {
          if (nvc0->vbo_push_hint) {
             nvc0->vbo_fifo = ~0;
@@ -230,14 +233,27 @@ nvc0_update_user_vbufs(struct nvc0_context *nvc0)
       MARK_RING (chan, 6, 4);
       BEGIN_RING_1I(chan, RING_3D(VERTEX_ARRAY_SELECT), 5);
       OUT_RING  (chan, i);
-      OUT_RESRCh(chan, buf, size - 1, NOUVEAU_BO_RD);
-      OUT_RESRCl(chan, buf, size - 1, NOUVEAU_BO_RD);
+      OUT_RESRCh(chan, buf, base + size - 1, NOUVEAU_BO_RD);
+      OUT_RESRCl(chan, buf, base + size - 1, NOUVEAU_BO_RD);
       OUT_RESRCh(chan, buf, offset, NOUVEAU_BO_RD);
       OUT_RESRCl(chan, buf, offset, NOUVEAU_BO_RD);
    }
    nvc0->vbo_dirty = TRUE;
 }
 
+static INLINE void
+nvc0_release_user_vbufs(struct nvc0_context *nvc0)
+{
+   uint32_t vbo_user = nvc0->vbo_user;
+
+   while (vbo_user) {
+      int i = ffs(vbo_user) - 1;
+      vbo_user &= ~(1 << i);
+
+      nvc0_buffer_release_gpu_storage(nvc0_resource(nvc0->vtxbuf[i].buffer));
+   }
+}
+
 void
 nvc0_vertex_arrays_validate(struct nvc0_context *nvc0)
 {
@@ -564,6 +580,9 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
    nvc0->vbo_min_index = info->min_index;
    nvc0->vbo_max_index = info->max_index;
 
+   if (nvc0->vbo_push_hint != !!nvc0->vbo_fifo)
+      nvc0->dirty |= NVC0_NEW_ARRAYS;
+
    if (nvc0->vbo_user && !(nvc0->dirty & (NVC0_NEW_VERTEX | NVC0_NEW_ARRAYS)))
       nvc0_update_user_vbufs(nvc0);
 
@@ -621,4 +640,6 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
                          info->mode, info->start, info->count,
                          info->instance_count, info->index_bias);
    }
+
+   nvc0_release_user_vbufs(nvc0);
 }