nouveau_vbo_t.c revision 43c347c63ee10db95bd912fc39b1127fa35305a4
1bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/*
2bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * Copyright (C) 2009-2010 Francisco Jerez.
3bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * All Rights Reserved.
4bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez *
5bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * Permission is hereby granted, free of charge, to any person obtaining
6bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * a copy of this software and associated documentation files (the
7bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * "Software"), to deal in the Software without restriction, including
8bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * without limitation the rights to use, copy, modify, merge, publish,
9bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * distribute, sublicense, and/or sell copies of the Software, and to
10bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * permit persons to whom the Software is furnished to do so, subject to
11bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * the following conditions:
12bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez *
13bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * The above copyright notice and this permission notice (including the
14bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * next paragraph) shall be included in all copies or substantial
15bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * portions of the Software.
16bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez *
17bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez *
25bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez */
26bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
27bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_bufferobj.h"
2843c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez#include "nouveau_util.h"
2943c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez
3043c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez#include "main/bufferobj.h"
3143c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez#include "main/image.h"
32bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
33bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Arbitrary pushbuf length we can assume we can get with a single
34bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * WAIT_RING. */
35bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define PUSHBUF_DWORDS 2048
36bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
37bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Functions to set up struct nouveau_array_state from something like
38bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * a GL array or index buffer. */
39bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
40bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
41bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvbo_init_array(struct nouveau_array_state *a, int attr, int stride,
42bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	       int fields, int type, struct gl_buffer_object *obj,
43bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	       const void *ptr, GLboolean map)
44bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
45bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	a->attr = attr;
46bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	a->stride = stride;
47bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	a->fields = fields;
48bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	a->type = type;
49bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
50bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (_mesa_is_bufferobj(obj)) {
51bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		nouveau_bo_ref(to_nouveau_bufferobj(obj)->bo, &a->bo);
52bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		a->offset = (intptr_t)ptr;
53bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
54bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (map) {
55bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			nouveau_bo_map(a->bo, NOUVEAU_BO_RD);
56bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			a->buf = a->bo->map + a->offset;
57bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		} else {
58bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			a->buf = NULL;
59bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		}
60bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
61bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	} else {
62bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		nouveau_bo_ref(NULL, &a->bo);
63bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		a->offset = 0;
6443c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez
6543c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez		if (map)
6643c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez			a->buf = ptr;
6743c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez		else
6843c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez			a->buf = NULL;
69bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
70bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
71bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (a->buf)
72bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		get_array_extract(a, &a->extract_u, &a->extract_f);
73bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
74bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
75bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
76bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvbo_deinit_array(struct nouveau_array_state *a)
77bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
78bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (a->bo) {
79bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (a->bo->map)
80bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			nouveau_bo_unmap(a->bo);
81bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		nouveau_bo_ref(NULL, &a->bo);
82bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
83bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
84bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	a->buf = NULL;
85bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	a->fields = 0;
86bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
87bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
88bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
89bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvbo_init_arrays(GLcontext *ctx, const struct _mesa_index_buffer *ib,
90bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		const struct gl_client_array **arrays)
91bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
92bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_render_state *render = to_render_state(ctx);
93bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i;
94bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
95bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (ib)
96bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_init_array(&render->ib, 0, 0, ib->count, ib->type,
97bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			       ib->obj, ib->ptr, GL_TRUE);
98bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
99bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	for (i = 0; i < render->attr_count; i++) {
100bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		int attr = render->map[i];
101bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
102bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (attr >= 0) {
103bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			const struct gl_client_array *array = arrays[attr];
10443c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez			int stride;
10543c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez
10643c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez			if (render->mode == VBO &&
10743c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez			    !_mesa_is_bufferobj(array->BufferObj))
10843c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez				/* Pack client buffers. */
10943c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez				stride = align(_mesa_sizeof_type(array->Type)
11043c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez					       * array->Size, 4);
11143c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez			else
11243c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez				stride = array->StrideB;
113bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
114bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			vbo_init_array(&render->attrs[attr], attr,
11543c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez				       stride, array->Size, array->Type,
11643c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez				       array->BufferObj, array->Ptr,
11743c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez				       render->mode == IMM);
118bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		}
119bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
120bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
121bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
122bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
123bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvbo_deinit_arrays(GLcontext *ctx, const struct _mesa_index_buffer *ib,
124bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		const struct gl_client_array **arrays)
125bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
126bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_render_state *render = to_render_state(ctx);
127bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i;
128bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
129bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (ib)
130bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_deinit_array(&render->ib);
131bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
132bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	for (i = 0; i < render->attr_count; i++) {
133bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		int *attr = &render->map[i];
134bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
135bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (*attr >= 0) {
136bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			vbo_deinit_array(&render->attrs[*attr]);
137bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			*attr = -1;
138bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		}
139bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
140bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
141bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	render->attr_count = 0;
142bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
143bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
144bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Make some rendering decisions from the GL context. */
145bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
146bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
147bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvbo_choose_render_mode(GLcontext *ctx, const struct gl_client_array **arrays)
148bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
149bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_render_state *render = to_render_state(ctx);
150bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i;
151bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
152bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	render->mode = VBO;
153bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
154bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (ctx->Light.Enabled) {
155bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		for (i = 0; i < MAT_ATTRIB_MAX; i++) {
156bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			if (arrays[VERT_ATTRIB_GENERIC0 + i]->StrideB) {
157bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				render->mode = IMM;
158bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				break;
159bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			}
160bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		}
161bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
162bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
163bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (render->mode == VBO)
164bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		render->attr_count = NUM_VERTEX_ATTRS;
165bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	else
166bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		render->attr_count = 0;
167bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
168bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
169bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
170bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvbo_emit_attr(GLcontext *ctx, const struct gl_client_array **arrays, int attr)
171bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
172bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_channel *chan = context_chan(ctx);
173bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_render_state *render = to_render_state(ctx);
174bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	const struct gl_client_array *array = arrays[attr];
175bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_array_state *a = &render->attrs[attr];
176bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	RENDER_LOCALS(ctx);
177bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
178bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!array->StrideB) {
179bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (attr >= VERT_ATTRIB_GENERIC0)
180bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			/* nouveau_update_state takes care of materials. */
181bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			return;
182bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
183bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		/* Constant attribute. */
184bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_init_array(a, attr, array->StrideB, array->Size,
185bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			       array->Type, array->BufferObj, array->Ptr,
186bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			       GL_TRUE);
187bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		EMIT_IMM(ctx, a, 0);
188bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_deinit_array(a);
189bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
190bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	} else {
191bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		/* Varying attribute. */
192bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		struct nouveau_attr_info *info = &TAG(vertex_attrs)[attr];
193bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
194bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (render->mode == VBO) {
195bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			render->map[info->vbo_index] = attr;
196bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			render->vertex_size += array->_ElementSize;
197bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		} else {
198bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			render->map[render->attr_count++] = attr;
199bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			render->vertex_size += 4 * info->imm_fields;
200bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		}
201bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
202bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
203bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
204bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define MAT(a) (VERT_ATTRIB_GENERIC0 + MAT_ATTRIB_##a)
205bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
206bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
207bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvbo_choose_attrs(GLcontext *ctx, const struct gl_client_array **arrays)
208bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
209bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_render_state *render = to_render_state(ctx);
210bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i;
211bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
212bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	/* Reset the vertex size. */
213bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	render->vertex_size = 0;
214bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
215bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	vbo_emit_attr(ctx, arrays, VERT_ATTRIB_COLOR0);
216bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (ctx->Fog.ColorSumEnabled && !ctx->Light.Enabled)
217bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_emit_attr(ctx, arrays, VERT_ATTRIB_COLOR1);
218bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
219bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
220bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (ctx->Texture._EnabledCoordUnits & (1 << i))
221bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			vbo_emit_attr(ctx, arrays, VERT_ATTRIB_TEX0 + i);
222bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
223bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
224bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (ctx->Fog.Enabled && ctx->Fog.FogCoordinateSource == GL_FOG_COORD)
225bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_emit_attr(ctx, arrays, VERT_ATTRIB_FOG);
226bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
227bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (ctx->Light.Enabled) {
228bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_emit_attr(ctx, arrays, VERT_ATTRIB_NORMAL);
229bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
230bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_emit_attr(ctx, arrays, MAT(FRONT_AMBIENT));
231bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_emit_attr(ctx, arrays, MAT(FRONT_DIFFUSE));
232bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_emit_attr(ctx, arrays, MAT(FRONT_SPECULAR));
233bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_emit_attr(ctx, arrays, MAT(FRONT_SHININESS));
234bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
235bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (ctx->Light.Model.TwoSide) {
236bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			vbo_emit_attr(ctx, arrays, MAT(BACK_AMBIENT));
237bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			vbo_emit_attr(ctx, arrays, MAT(BACK_DIFFUSE));
238bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			vbo_emit_attr(ctx, arrays, MAT(BACK_SPECULAR));
239bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			vbo_emit_attr(ctx, arrays, MAT(BACK_SHININESS));
240bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		}
241bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
242bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
243bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	vbo_emit_attr(ctx, arrays, VERT_ATTRIB_POS);
244bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
245bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
246bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
247bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco JerezTAG(vbo_render_prims)(GLcontext *ctx, const struct gl_client_array **arrays,
248bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		      const struct _mesa_prim *prims, GLuint nr_prims,
249bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		      const struct _mesa_index_buffer *ib,
250bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		      GLboolean index_bounds_valid,
251bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		      GLuint min_index, GLuint max_index);
252bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
253bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic GLboolean
254bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvbo_maybe_split(GLcontext *ctx, const struct gl_client_array **arrays,
255bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	    const struct _mesa_prim *prims, GLuint nr_prims,
256bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	    const struct _mesa_index_buffer *ib,
257bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	    GLuint min_index, GLuint max_index)
258bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
259bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_context *nctx = to_nouveau_context(ctx);
260bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	unsigned pushbuf_avail = PUSHBUF_DWORDS - 2 * nctx->bo.count,
261bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vert_avail = get_max_vertices(ctx, NULL, pushbuf_avail),
262bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		idx_avail = get_max_vertices(ctx, ib, pushbuf_avail);
263bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
264bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if ((ib && ib->count > idx_avail) ||
265bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	    (!ib && max_index - min_index > vert_avail)) {
266bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		struct split_limits limits = {
267bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			.max_verts = vert_avail,
268bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			.max_indices = idx_avail,
269bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			.max_vb_size = ~0,
270bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		};
271bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
272bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_split_prims(ctx, arrays, prims, nr_prims, ib, min_index,
273bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				max_index, TAG(vbo_render_prims), &limits);
274bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return GL_TRUE;
275bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
276bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
277bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return GL_FALSE;
278bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
279bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
280bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* VBO rendering path. */
281bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
282bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
283bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvbo_bind_vertices(GLcontext *ctx, const struct gl_client_array **arrays,
284bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		  GLint basevertex, GLuint min_index, GLuint max_index)
285bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
286bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_render_state *render = to_render_state(ctx);
287bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i;
288bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
289bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	for (i = 0; i < NUM_VERTEX_ATTRS; i++) {
290bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		int attr = render->map[i];
291bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
292bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (attr >= 0) {
293bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			const struct gl_client_array *array = arrays[attr];
294bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			struct nouveau_array_state *a = &render->attrs[attr];
29543c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez			unsigned delta = (basevertex + min_index)
29643c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez				* array->StrideB;
297bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
298bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			if (a->bo) {
299bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				a->offset = (intptr_t)array->Ptr + delta;
300bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			} else {
30143c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez				int j, n = max_index - min_index + 1;
30243c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez				char *sp = (char *)array->Ptr + delta;
30343c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez				char *dp = get_scratch_vbo(ctx, n * a->stride,
30443c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez							   &a->bo, &a->offset);
30543c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez
30643c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez				for (j = 0; j < n; j++)
30743c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez					memcpy(dp + j * a->stride,
30843c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez					       sp + j * array->StrideB,
30943c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez					       a->stride);
310bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			}
311bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		}
312bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
313bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
314bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	TAG(render_bind_vertices)(ctx);
315bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
316bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
317bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
318bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvbo_draw_vbo(GLcontext *ctx, const struct gl_client_array **arrays,
319bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	     const struct _mesa_prim *prims, GLuint nr_prims,
320bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	     const struct _mesa_index_buffer *ib, GLuint min_index,
321bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	     GLuint max_index)
322bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
323bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_channel *chan = context_chan(ctx);
324bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	dispatch_t dispatch;
325bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int delta = -min_index, basevertex = 0, i;
326bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	RENDER_LOCALS(ctx);
327bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
328bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	get_array_dispatch(&to_render_state(ctx)->ib, &dispatch);
329bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
330bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	TAG(render_set_format)(ctx);
331bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
332bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	for (i = 0; i < nr_prims; i++) {
333bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		unsigned start = prims[i].start,
334bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			count = prims[i].count;
335bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
336bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (i == 0 || basevertex != prims[i].basevertex) {
337bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			basevertex = prims[i].basevertex;
338bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			vbo_bind_vertices(ctx, arrays, basevertex,
339bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez					  min_index, max_index);
340bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		}
341bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
34241b19c279a0eae61f0f95c3b66376a25635241fdJohannes Obermayr		if (count > get_max_vertices(ctx, ib, AVAIL_RING(chan)))
343bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			WAIT_RING(chan, PUSHBUF_DWORDS);
344bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
345bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BATCH_BEGIN(nvgl_primitive(prims[i].mode));
346bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		dispatch(ctx, start, delta, count);
347bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BATCH_END();
348bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
349bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
350bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	FIRE_RING(chan);
351bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
352bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
353bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Immediate rendering path. */
354bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
355bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic unsigned
356bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezextract_id(struct nouveau_array_state *a, int i, int j)
357bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
358bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return j;
359bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
360bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
361bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
362bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvbo_draw_imm(GLcontext *ctx, const struct gl_client_array **arrays,
363bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	     const struct _mesa_prim *prims, GLuint nr_prims,
364bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	     const struct _mesa_index_buffer *ib, GLuint min_index,
365bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	     GLuint max_index)
366bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
367bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_render_state *render = to_render_state(ctx);
368bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_channel *chan = context_chan(ctx);
369bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	extract_u_t extract = ib ? render->ib.extract_u : extract_id;
370bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i, j, k;
371bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	RENDER_LOCALS(ctx);
372bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
373bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	for (i = 0; i < nr_prims; i++) {
374bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		unsigned start = prims[i].start,
375bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			end = start + prims[i].count;
376bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
377bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (prims[i].count > get_max_vertices(ctx, ib,
37841b19c279a0eae61f0f95c3b66376a25635241fdJohannes Obermayr						      AVAIL_RING(chan)))
379bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			WAIT_RING(chan, PUSHBUF_DWORDS);
380bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
381bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BATCH_BEGIN(nvgl_primitive(prims[i].mode));
382bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
383bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		for (; start < end; start++) {
384bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			j = prims[i].basevertex +
385bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				extract(&render->ib, 0, start);
386bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
387bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			for (k = 0; k < render->attr_count; k++)
388bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				EMIT_IMM(ctx, &render->attrs[render->map[k]],
389bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez					 j);
390bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		}
391bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
392bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BATCH_END();
393bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
394bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
395bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	FIRE_RING(chan);
396bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
397bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
398bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* draw_prims entry point when we're doing hw-tnl. */
399bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
400bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
401bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco JerezTAG(vbo_render_prims)(GLcontext *ctx, const struct gl_client_array **arrays,
402bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		      const struct _mesa_prim *prims, GLuint nr_prims,
403bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		      const struct _mesa_index_buffer *ib,
404bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		      GLboolean index_bounds_valid,
405bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		      GLuint min_index, GLuint max_index)
406bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
407bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_render_state *render = to_render_state(ctx);
408bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
409bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!index_bounds_valid)
410bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
411bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
412bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	vbo_choose_render_mode(ctx, arrays);
413bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	vbo_choose_attrs(ctx, arrays);
414bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
415bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (vbo_maybe_split(ctx, arrays, prims, nr_prims, ib, min_index,
416bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			    max_index))
417bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return;
418bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
419bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	vbo_init_arrays(ctx, ib, arrays);
420bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
421bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (render->mode == VBO)
422bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_draw_vbo(ctx, arrays, prims, nr_prims, ib, min_index,
423bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			     max_index);
424bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	else
425bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_draw_imm(ctx, arrays, prims, nr_prims, ib, min_index,
426bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			     max_index);
427bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
428bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	vbo_deinit_arrays(ctx, ib, arrays);
429bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
430