struct translate *translate;
bool primitive_restart;
+
+ bool need_vertex_id;
+ int32_t index_bias;
+
uint32_t prim;
uint32_t restart_index;
uint32_t instance_id;
size = ctx->vertex_words * nr;
+ if (unlikely(ctx->need_vertex_id)) {
+ BEGIN_NV04(ctx->push, NV84_3D(VERTEX_ID_BASE), 1);
+ PUSH_DATA (ctx->push, *elts + ctx->index_bias);
+ }
+
BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
ctx->translate->run_elts8(ctx->translate, elts, nr, 0, ctx->instance_id,
size = ctx->vertex_words * nr;
+ if (unlikely(ctx->need_vertex_id)) {
+ BEGIN_NV04(ctx->push, NV84_3D(VERTEX_ID_BASE), 1);
+ PUSH_DATA (ctx->push, *elts + ctx->index_bias);
+ }
+
BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
ctx->translate->run_elts16(ctx->translate, elts, nr, 0, ctx->instance_id,
size = ctx->vertex_words * nr;
+ if (unlikely(ctx->need_vertex_id)) {
+ BEGIN_NV04(ctx->push, NV84_3D(VERTEX_ID_BASE), 1);
+ PUSH_DATA (ctx->push, *elts + ctx->index_bias);
+ }
+
BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
ctx->translate->run_elts(ctx->translate, elts, nr, 0, ctx->instance_id,
static void
emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count)
{
+ uint32_t elts = 0;
+
while (count) {
unsigned push = MIN2(count, ctx->packet_vertex_limit);
unsigned size = ctx->vertex_words * push;
+ if (unlikely(ctx->need_vertex_id)) {
+ /* For non-indexed draws, gl_VertexID goes up after each vertex. */
+ BEGIN_NV04(ctx->push, NV84_3D(VERTEX_ID_BASE), 1);
+ PUSH_DATA (ctx->push, elts++);
+ }
+
BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
ctx->translate->run(ctx->translate, start, push, 0, ctx->instance_id,
ctx.push = nv50->base.pushbuf;
ctx.translate = nv50->vertex->translate;
- ctx.packet_vertex_limit = nv50->vertex->packet_vertex_limit;
+
+ ctx.need_vertex_id = nv50->screen->base.class_3d >= NV84_3D_CLASS &&
+ nv50->vertprog->vp.need_vertex_id && (nv50->vertex->num_elements < 32);
+ ctx.index_bias = info->index_bias;
+
+ /* For indexed draws, gl_VertexID must be emitted for every vertex. */
+ ctx.packet_vertex_limit =
+ ctx.need_vertex_id ? 1 : nv50->vertex->packet_vertex_limit;
ctx.vertex_words = nv50->vertex->vertex_size;
assert(nv50->num_vtxbufs <= PIPE_MAX_ATTRIBS);
ctx.instance_id++;
ctx.prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
}
+
+ if (unlikely(ctx.need_vertex_id)) {
+ /* Reset gl_VertexID to prevent future indexed draws to be confused. */
+ BEGIN_NV04(ctx.push, NV84_3D(VERTEX_ID_BASE), 1);
+ PUSH_DATA (ctx.push, nv50->state.index_bias);
+ }
}
uint64_t addrs[PIPE_MAX_ATTRIBS];
uint32_t limits[PIPE_MAX_ATTRIBS];
struct nouveau_pushbuf *push = nv50->base.pushbuf;
- struct nv50_vertex_stateobj dummy = {};
- struct nv50_vertex_stateobj *vertex = nv50->vertex ? nv50->vertex : &dummy;
+ struct nv50_vertex_stateobj *vertex = nv50->vertex;
struct pipe_vertex_buffer *vb;
struct nv50_vertex_element *ve;
uint32_t mask;
unsigned i;
const unsigned n = MAX2(vertex->num_elements, nv50->state.num_vtxelts);
- /* A vertexid is not generated for inline data uploads. Have to use a
- * VBO. This check must come after the vertprog has been validated,
- * otherwise vertexid may be unset.
- */
- assert(nv50->vertprog->translated);
- if (nv50->vertprog->vp.vertexid)
- nv50->vbo_push_hint = 0;
-
if (unlikely(vertex->need_conversion))
nv50->vbo_fifo = ~0;
else