summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2016-01-29 20:28:12 -0500
committerIlia Mirkin <[email protected]>2016-01-29 22:10:42 -0500
commit438d421f8bb3f65402701628c3504c0ad04184c0 (patch)
tree7f19fa5990721611051b785019f334c20cdd9d23
parent899b1b98a4ab094456632e08ce01ffb106519012 (diff)
nvc0: avoid crashing when there are holes in vertex array bindings
When using the "shared" vertex array configuration strategy, we bind each of the buffers as a separate array. However there can be holes in such vertex buffer lists, so just emit a disable for those. Signed-off-by: Ilia Mirkin <[email protected]> Cc: [email protected]
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
index ad79d1cbb9c..e8ee4865747 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
@@ -334,7 +334,7 @@ nvc0_validate_vertex_buffers(struct nvc0_context *nvc0)
b = ve->pipe.vertex_buffer_index;
vb = &nvc0->vtxbuf[b];
- if (!vb->buffer) {
+ if (nvc0->vbo_user & (1 << b)) {
if (!(nvc0->constant_vbos & (1 << b))) {
if (ve->pipe.instance_divisor) {
BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_DIVISOR(i)), 1);
@@ -352,13 +352,13 @@ nvc0_validate_vertex_buffers(struct nvc0_context *nvc0)
if (unlikely(ve->pipe.instance_divisor)) {
BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_FETCH(i)), 4);
- PUSH_DATA (push, (1 << 12) | vb->stride);
+ PUSH_DATA (push, NVC0_3D_VERTEX_ARRAY_FETCH_ENABLE | vb->stride);
PUSH_DATAh(push, res->address + offset);
PUSH_DATA (push, res->address + offset);
PUSH_DATA (push, ve->pipe.instance_divisor);
} else {
BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_FETCH(i)), 3);
- PUSH_DATA (push, (1 << 12) | vb->stride);
+ PUSH_DATA (push, NVC0_3D_VERTEX_ARRAY_FETCH_ENABLE | vb->stride);
PUSH_DATAh(push, res->address + offset);
PUSH_DATA (push, res->address + offset);
}
@@ -395,6 +395,10 @@ nvc0_validate_vertex_buffers_shared(struct nvc0_context *nvc0)
}
/* address/value set in nvc0_update_user_vbufs_shared */
continue;
+ } else if (!vb->buffer) {
+ /* there can be holes in the vertex buffer lists */
+ IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_FETCH(b)), 0);
+ continue;
}
buf = nv04_resource(vb->buffer);
offset = vb->buffer_offset;
@@ -410,6 +414,12 @@ nvc0_validate_vertex_buffers_shared(struct nvc0_context *nvc0)
BCTX_REFN(nvc0->bufctx_3d, VTX, buf, RD);
}
+ /* If there are more elements than buffers, we might not have unset
+ * fetching on the later elements.
+ */
+ for (; b < nvc0->vertex->num_elements; ++b)
+ IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_FETCH(b)), 0);
+
if (nvc0->vbo_user)
nvc0_update_user_vbufs_shared(nvc0);
}