summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nvc0/nvc0_vbo.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/nvc0/nvc0_vbo.c')
-rw-r--r--src/gallium/drivers/nvc0/nvc0_vbo.c95
1 files changed, 39 insertions, 56 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c b/src/gallium/drivers/nvc0/nvc0_vbo.c
index a51a887ed89..2db43d8704b 100644
--- a/src/gallium/drivers/nvc0/nvc0_vbo.c
+++ b/src/gallium/drivers/nvc0/nvc0_vbo.c
@@ -54,12 +54,13 @@ nvc0_vertex_state_create(struct pipe_context *pipe,
assert(num_elements);
so = MALLOC(sizeof(*so) +
- (num_elements - 1) * sizeof(struct nvc0_vertex_element));
+ num_elements * sizeof(struct nvc0_vertex_element));
if (!so)
return NULL;
so->num_elements = num_elements;
so->instance_elts = 0;
so->instance_bufs = 0;
+ so->need_conversion = FALSE;
transkey.nr_elements = 0;
transkey.output_stride = 0;
@@ -83,6 +84,7 @@ nvc0_vertex_state_create(struct pipe_context *pipe,
return NULL;
}
so->element[i].state = nvc0_format_table[fmt].vtx;
+ so->need_conversion = TRUE;
}
so->element[i].state |= i;
@@ -152,7 +154,7 @@ nvc0_vbuf_range(struct nvc0_context *nvc0, int vbi,
if (unlikely(nvc0->vertex->instance_bufs & (1 << vbi))) {
/* TODO: use min and max instance divisor to get a proper range */
*base = 0;
- *size = (nvc0->vtxbuf[vbi].max_index + 1) * nvc0->vtxbuf[vbi].stride;
+ *size = nvc0->vtxbuf[vbi].buffer->width0;
} else {
assert(nvc0->vbo_max_index != ~0);
*base = nvc0->vbo_min_index * nvc0->vtxbuf[vbi].stride;
@@ -171,12 +173,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;
@@ -227,16 +232,30 @@ nvc0_update_user_vbufs(struct nvc0_context *nvc0)
}
offset = vb->buffer_offset + ve->src_offset;
+ 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)
{
@@ -246,7 +265,12 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0)
struct nvc0_vertex_element *ve;
unsigned i;
- nvc0_prevalidate_vbufs(nvc0);
+ if (unlikely(vertex->need_conversion)) {
+ nvc0->vbo_fifo = ~0;
+ nvc0->vbo_user = 0;
+ } else {
+ nvc0_prevalidate_vbufs(nvc0);
+ }
BEGIN_RING(chan, RING_3D(VERTEX_ATTRIB_FORMAT(0)), vertex->num_elements);
for (i = 0; i < vertex->num_elements; ++i) {
@@ -292,6 +316,7 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0)
size = vb->buffer->width0;
offset = ve->pipe.src_offset + vb->buffer_offset;
+ MARK_RING (chan, 8, 4);
BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
OUT_RING (chan, (1 << 12) | vb->stride);
BEGIN_RING_1I(chan, RING_3D(VERTEX_ARRAY_SELECT), 5);
@@ -346,57 +371,10 @@ nvc0_draw_vbo_flush_notify(struct nouveau_channel *chan)
{
struct nvc0_context *nvc0 = chan->user_private;
- nvc0_bufctx_emit_relocs(nvc0);
-}
+ nvc0_screen_fence_update(nvc0->screen, TRUE);
-#if 0
-static struct nouveau_bo *
-nvc0_tfb_setup(struct nvc0_context *nvc0)
-{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
- struct nouveau_bo *tfb = NULL;
- int ret, i;
-
- ret = nouveau_bo_new(nvc0->screen->base.device,
- NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, &tfb);
- if (ret)
- return NULL;
-
- ret = nouveau_bo_map(tfb, NOUVEAU_BO_WR);
- if (ret)
- return NULL;
- memset(tfb->map, 0xee, 8 * 4 * 3);
- nouveau_bo_unmap(tfb);
-
- BEGIN_RING(chan, RING_3D(TFB_ENABLE), 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_3D(TFB_BUFFER_ENABLE(0)), 5);
- OUT_RING (chan, 1);
- OUT_RELOCh(chan, tfb, 0, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
- OUT_RELOCl(chan, tfb, 0, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
- OUT_RING (chan, tfb->size);
- OUT_RING (chan, 0); /* TFB_PRIMITIVE_ID(0) */
- BEGIN_RING(chan, RING_3D(TFB_UNK0700(0)), 3);
- OUT_RING (chan, 0);
- OUT_RING (chan, 8); /* TFB_VARYING_COUNT(0) */
- OUT_RING (chan, 32); /* TFB_BUFFER_STRIDE(0) */
- BEGIN_RING(chan, RING_3D(TFB_VARYING_LOCS(0)), 2);
- OUT_RING (chan, 0x1f1e1d1c);
- OUT_RING (chan, 0xa3a2a1a0);
- for (i = 1; i < 4; ++i) {
- BEGIN_RING(chan, RING_3D(TFB_BUFFER_ENABLE(i)), 1);
- OUT_RING (chan, 0);
- }
- BEGIN_RING(chan, RING_3D(TFB_ENABLE), 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_3D_(0x135c), 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_3D_(0x135c), 1);
- OUT_RING (chan, 0);
-
- return tfb;
+ nvc0_bufctx_emit_relocs(nvc0);
}
-#endif
static void
nvc0_draw_arrays(struct nvc0_context *nvc0,
@@ -422,7 +400,7 @@ nvc0_draw_arrays(struct nvc0_context *nvc0,
prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
}
- chan->flush_notify = NULL;
+ chan->flush_notify = nvc0_default_flush_notify;
}
static void
@@ -592,7 +570,7 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten,
}
}
- chan->flush_notify = NULL;
+ chan->flush_notify = nvc0_default_flush_notify;
}
void
@@ -611,6 +589,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);
@@ -668,4 +649,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);
}