summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2011-02-15 19:12:41 +0100
committerChristoph Bumiller <[email protected]>2011-02-16 15:45:30 +0100
commita3c62afa7c7f3435b3c28bee417e652c9bb018e6 (patch)
tree6d80acc6b97000f10088d54e2e809efd5f77a12b /src
parentfc5ab1b19780ef97c5e7f6257a2d91121503bd53 (diff)
nvc0: fix user vertex buffer updates
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/nvc0/nvc0_buffer.c19
-rw-r--r--src/gallium/drivers/nvc0/nvc0_resource.h3
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.h6
-rw-r--r--src/gallium/drivers/nvc0/nvc0_vbo.c25
4 files changed, 42 insertions, 11 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_buffer.c b/src/gallium/drivers/nvc0/nvc0_buffer.c
index ea3e642a448..f16671ac7ff 100644
--- a/src/gallium/drivers/nvc0/nvc0_buffer.c
+++ b/src/gallium/drivers/nvc0/nvc0_buffer.c
@@ -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);
diff --git a/src/gallium/drivers/nvc0/nvc0_resource.h b/src/gallium/drivers/nvc0/nvc0_resource.h
index 17e79642a6d..709e6157f55 100644
--- a/src/gallium/drivers/nvc0/nvc0_resource.h
+++ b/src/gallium/drivers/nvc0/nvc0_resource.h
@@ -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);
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.h b/src/gallium/drivers/nvc0/nvc0_screen.h
index 1fac142e2be..3b676fd21a1 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.h
+++ b/src/gallium/drivers/nvc0/nvc0_screen.h
@@ -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);
+ }
}
diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c b/src/gallium/drivers/nvc0/nvc0_vbo.c
index 80e05823759..fb135725c3f 100644
--- a/src/gallium/drivers/nvc0/nvc0_vbo.c
+++ b/src/gallium/drivers/nvc0/nvc0_vbo.c
@@ -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);
}