nouveau_vbo_t.c revision 57382e71ef892a36ca2171fe8758aba6c9c885e6
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
3457382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez * call to WAIT_RING. */
35c25fcf5aa5beccd7731706b8f85682170a2eca56Francisco Jerez#define PUSHBUF_DWORDS 65536
36bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
3757382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez/* Functions to turn GL arrays or index buffers into nouveau_array
3857382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez * structures. */
39bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
407f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerezstatic int
41f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergget_array_stride(struct gl_context *ctx, const struct gl_client_array *a)
427f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez{
437f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez	struct nouveau_render_state *render = to_render_state(ctx);
447f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez
457f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez	if (render->mode == VBO && !_mesa_is_bufferobj(a->BufferObj))
467f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez		/* Pack client buffers. */
477f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez		return align(_mesa_sizeof_type(a->Type) * a->Size, 4);
487f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez	else
497f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez		return a->StrideB;
507f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez}
517f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez
52bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
53f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_init_arrays(struct gl_context *ctx, const struct _mesa_index_buffer *ib,
54bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		const struct gl_client_array **arrays)
55bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
56bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_render_state *render = to_render_state(ctx);
579d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez	GLboolean imm = (render->mode == IMM);
589d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez	int i, attr;
59bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
60bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (ib)
6157382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez		nouveau_init_array(&render->ib, 0, 0, ib->count, ib->type,
6257382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez				   ib->obj, ib->ptr, GL_TRUE);
63bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
649d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez	FOR_EACH_BOUND_ATTR(render, i, attr) {
659d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez		const struct gl_client_array *array = arrays[attr];
66bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
6757382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez		nouveau_init_array(&render->attrs[attr], attr,
6857382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez				   get_array_stride(ctx, array),
6957382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez				   array->Size, array->Type,
7057382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez				   array->BufferObj,
7157382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez				   array->Ptr, imm);
72bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
73bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
74bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
75bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
76f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_deinit_arrays(struct gl_context *ctx, const struct _mesa_index_buffer *ib,
779d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez		  const struct gl_client_array **arrays)
78bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
79bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_render_state *render = to_render_state(ctx);
809d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez	int i, attr;
81bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
82bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (ib)
8357382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez		nouveau_cleanup_array(&render->ib);
84bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
859d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez	FOR_EACH_BOUND_ATTR(render, i, attr) {
8657382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez		struct nouveau_array *a = &render->attrs[attr];
87bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
8857382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez		nouveau_deinit_array(a);
899d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez		render->map[i] = -1;
90bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
91bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
92bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	render->attr_count = 0;
9322c83ac47a50ed1fdab59476886a7e56910a653aFrancisco Jerez	context_bctx(ctx, VERTEX);
94bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
95bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
96bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Make some rendering decisions from the GL context. */
97bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
98bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
99f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_choose_render_mode(struct gl_context *ctx, const struct gl_client_array **arrays)
100bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
101bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_render_state *render = to_render_state(ctx);
102bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i;
103bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
104bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	render->mode = VBO;
105bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
106bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (ctx->Light.Enabled) {
107bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		for (i = 0; i < MAT_ATTRIB_MAX; i++) {
108bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			if (arrays[VERT_ATTRIB_GENERIC0 + i]->StrideB) {
109bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				render->mode = IMM;
110bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				break;
111bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			}
112bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		}
113bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
114bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
115bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
116bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
11757382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerezvbo_emit_attr(struct gl_context *ctx, const struct gl_client_array **arrays,
11857382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez	      int attr)
119bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
120bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_channel *chan = context_chan(ctx);
121bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_render_state *render = to_render_state(ctx);
122bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	const struct gl_client_array *array = arrays[attr];
12357382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez	struct nouveau_array *a = &render->attrs[attr];
124bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	RENDER_LOCALS(ctx);
125bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
126bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!array->StrideB) {
127bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (attr >= VERT_ATTRIB_GENERIC0)
128bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			/* nouveau_update_state takes care of materials. */
129bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			return;
130bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
131bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		/* Constant attribute. */
13257382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez		nouveau_init_array(a, attr, array->StrideB, array->Size,
13357382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez				   array->Type, array->BufferObj, array->Ptr,
13457382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez				   GL_TRUE);
135bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		EMIT_IMM(ctx, a, 0);
13657382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez		nouveau_deinit_array(a);
137bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
138bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	} else {
139bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		/* Varying attribute. */
140bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		struct nouveau_attr_info *info = &TAG(vertex_attrs)[attr];
141bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
142bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (render->mode == VBO) {
143bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			render->map[info->vbo_index] = attr;
144bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			render->vertex_size += array->_ElementSize;
1459d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez			render->attr_count = MAX2(render->attr_count,
1469d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez						  info->vbo_index + 1);
147bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		} else {
148bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			render->map[render->attr_count++] = attr;
149bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			render->vertex_size += 4 * info->imm_fields;
150bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		}
1519d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez
152bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
153bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
154bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
155bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define MAT(a) (VERT_ATTRIB_GENERIC0 + MAT_ATTRIB_##a)
156bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
157bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
158f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_choose_attrs(struct gl_context *ctx, const struct gl_client_array **arrays)
159bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
160bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_render_state *render = to_render_state(ctx);
161bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	int i;
162bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
163bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	/* Reset the vertex size. */
164bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	render->vertex_size = 0;
1659d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez	render->attr_count = 0;
166bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
167bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	vbo_emit_attr(ctx, arrays, VERT_ATTRIB_COLOR0);
168bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (ctx->Fog.ColorSumEnabled && !ctx->Light.Enabled)
169bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_emit_attr(ctx, arrays, VERT_ATTRIB_COLOR1);
170bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
171bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
172bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (ctx->Texture._EnabledCoordUnits & (1 << i))
173bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			vbo_emit_attr(ctx, arrays, VERT_ATTRIB_TEX0 + i);
174bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
175bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
176bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (ctx->Fog.Enabled && ctx->Fog.FogCoordinateSource == GL_FOG_COORD)
177bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_emit_attr(ctx, arrays, VERT_ATTRIB_FOG);
178bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
179c944fb5ffe7cf16154d6395001f43a6c965cab1fFrancisco Jerez	if (ctx->Light.Enabled ||
180c944fb5ffe7cf16154d6395001f43a6c965cab1fFrancisco Jerez	    (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS))
181bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_emit_attr(ctx, arrays, VERT_ATTRIB_NORMAL);
182bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
183c944fb5ffe7cf16154d6395001f43a6c965cab1fFrancisco Jerez	if (ctx->Light.Enabled) {
184bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_emit_attr(ctx, arrays, MAT(FRONT_AMBIENT));
185bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_emit_attr(ctx, arrays, MAT(FRONT_DIFFUSE));
186bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_emit_attr(ctx, arrays, MAT(FRONT_SPECULAR));
187bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_emit_attr(ctx, arrays, MAT(FRONT_SHININESS));
188bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
189bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (ctx->Light.Model.TwoSide) {
190bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			vbo_emit_attr(ctx, arrays, MAT(BACK_AMBIENT));
191bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			vbo_emit_attr(ctx, arrays, MAT(BACK_DIFFUSE));
192bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			vbo_emit_attr(ctx, arrays, MAT(BACK_SPECULAR));
193bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			vbo_emit_attr(ctx, arrays, MAT(BACK_SHININESS));
194bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		}
195bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
196bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
197bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	vbo_emit_attr(ctx, arrays, VERT_ATTRIB_POS);
198bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
199bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
2007f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerezstatic int
201f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergget_max_client_stride(struct gl_context *ctx, const struct gl_client_array **arrays)
20280316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez{
20380316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez	struct nouveau_render_state *render = to_render_state(ctx);
2049d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez	int i, attr, s = 0;
20580316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez
2069d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez	FOR_EACH_BOUND_ATTR(render, i, attr) {
2079d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez		const struct gl_client_array *a = arrays[attr];
20880316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez
2099d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez		if (!_mesa_is_bufferobj(a->BufferObj))
2109d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez			s = MAX2(s, get_array_stride(ctx, a));
21180316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez	}
21280316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez
21380316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez	return s;
21480316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez}
21580316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez
216bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
217f9995b30756140724f41daf963fa06167912be7fKristian HøgsbergTAG(vbo_render_prims)(struct gl_context *ctx, const struct gl_client_array **arrays,
218bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		      const struct _mesa_prim *prims, GLuint nr_prims,
219bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		      const struct _mesa_index_buffer *ib,
220bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		      GLboolean index_bounds_valid,
221bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		      GLuint min_index, GLuint max_index);
222bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
223bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic GLboolean
224f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_maybe_split(struct gl_context *ctx, const struct gl_client_array **arrays,
225bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	    const struct _mesa_prim *prims, GLuint nr_prims,
226bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	    const struct _mesa_index_buffer *ib,
227bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	    GLuint min_index, GLuint max_index)
228bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
229bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_context *nctx = to_nouveau_context(ctx);
23080316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez	struct nouveau_render_state *render = to_render_state(ctx);
231d475eae50b15646efd83fa7f73ad7f2b40dd5206Francisco Jerez	unsigned pushbuf_avail = PUSHBUF_DWORDS - 2 * (nctx->bo.count +
232d475eae50b15646efd83fa7f73ad7f2b40dd5206Francisco Jerez						       render->attr_count),
233bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vert_avail = get_max_vertices(ctx, NULL, pushbuf_avail),
234bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		idx_avail = get_max_vertices(ctx, ib, pushbuf_avail);
23580316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez	int stride;
23680316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez
23780316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez	/* Try to keep client buffers smaller than the scratch BOs. */
238ea027bda8e4a7cdd8f131e01ab4ff80d6c6a3ab7Francisco Jerez	if (render->mode == VBO &&
239d475eae50b15646efd83fa7f73ad7f2b40dd5206Francisco Jerez	    (stride = get_max_client_stride(ctx, arrays)))
24080316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez		    vert_avail = MIN2(vert_avail,
241f2098e0fefbbcd72df4c8283d195beae4a113f35Francisco Jerez				      NOUVEAU_SCRATCH_SIZE / stride);
24280316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez
243ea027bda8e4a7cdd8f131e01ab4ff80d6c6a3ab7Francisco Jerez	if (max_index - min_index > vert_avail ||
244ea027bda8e4a7cdd8f131e01ab4ff80d6c6a3ab7Francisco Jerez	    (ib && ib->count > idx_avail)) {
245bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		struct split_limits limits = {
246bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			.max_verts = vert_avail,
247bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			.max_indices = idx_avail,
248bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			.max_vb_size = ~0,
249bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		};
250bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
251bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_split_prims(ctx, arrays, prims, nr_prims, ib, min_index,
252bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				max_index, TAG(vbo_render_prims), &limits);
253bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return GL_TRUE;
254bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
255bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
256bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return GL_FALSE;
257bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
258bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
259bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* VBO rendering path. */
260bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
261bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
262f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_bind_vertices(struct gl_context *ctx, const struct gl_client_array **arrays,
263bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		  GLint basevertex, GLuint min_index, GLuint max_index)
264bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
265bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_render_state *render = to_render_state(ctx);
2669d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez	int i, attr;
267bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
2689d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez	FOR_EACH_BOUND_ATTR(render, i, attr) {
2699d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez		const struct gl_client_array *array = arrays[attr];
27057382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez		struct nouveau_array *a = &render->attrs[attr];
2719d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez		unsigned delta = (basevertex + min_index)
2729d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez			* array->StrideB;
2739d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez
2749d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez		if (a->bo) {
2759d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez			/* Array in a buffer obj. */
2769d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez			a->offset = (intptr_t)array->Ptr + delta;
2779d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez		} else {
2789d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez			int j, n = max_index - min_index + 1;
2799d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez			char *sp = (char *)array->Ptr + delta;
2809d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez			char *dp = nouveau_get_scratch(
2819d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez				ctx, n * a->stride, &a->bo, &a->offset);
2829d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez
2839d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez			/* Array in client memory, move it to
2849d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez			 * a scratch buffer obj. */
2859d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez			for (j = 0; j < n; j++)
2869d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez				memcpy(dp + j * a->stride,
2879d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez				       sp + j * array->StrideB,
2889d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez				       a->stride);
289bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		}
290bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
291bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
292bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	TAG(render_bind_vertices)(ctx);
293bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
294bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
295bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
296f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_draw_vbo(struct gl_context *ctx, const struct gl_client_array **arrays,
297bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	     const struct _mesa_prim *prims, GLuint nr_prims,
298bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	     const struct _mesa_index_buffer *ib, GLuint min_index,
299bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	     GLuint max_index)
300bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
301bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_channel *chan = context_chan(ctx);
30257382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez	dispatch_t dispatch = get_array_dispatch(&to_render_state(ctx)->ib);
30357382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez	int i, delta = -min_index, basevertex = 0;
304bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	RENDER_LOCALS(ctx);
305bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
306bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	TAG(render_set_format)(ctx);
307bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
308bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	for (i = 0; i < nr_prims; i++) {
309bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		unsigned start = prims[i].start,
310bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			count = prims[i].count;
311bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
312bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (i == 0 || basevertex != prims[i].basevertex) {
313bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			basevertex = prims[i].basevertex;
314bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			vbo_bind_vertices(ctx, arrays, basevertex,
315bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez					  min_index, max_index);
316bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		}
317bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
31841b19c279a0eae61f0f95c3b66376a25635241fdJohannes Obermayr		if (count > get_max_vertices(ctx, ib, AVAIL_RING(chan)))
319bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			WAIT_RING(chan, PUSHBUF_DWORDS);
320bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
321bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BATCH_BEGIN(nvgl_primitive(prims[i].mode));
322bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		dispatch(ctx, start, delta, count);
323bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BATCH_END();
324bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
325bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
326bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
327bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Immediate rendering path. */
328bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
329bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic unsigned
33057382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerezextract_id(struct nouveau_array *a, int i, int j)
331bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
332bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	return j;
333bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
334bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
335bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
336f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_draw_imm(struct gl_context *ctx, const struct gl_client_array **arrays,
337bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	     const struct _mesa_prim *prims, GLuint nr_prims,
338bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	     const struct _mesa_index_buffer *ib, GLuint min_index,
339bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	     GLuint max_index)
340bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
341bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_render_state *render = to_render_state(ctx);
342bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_channel *chan = context_chan(ctx);
343bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	extract_u_t extract = ib ? render->ib.extract_u : extract_id;
3449d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez	int i, j, k, attr;
345bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	RENDER_LOCALS(ctx);
346bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
347bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	for (i = 0; i < nr_prims; i++) {
348bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		unsigned start = prims[i].start,
349bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			end = start + prims[i].count;
350bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
351bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		if (prims[i].count > get_max_vertices(ctx, ib,
35241b19c279a0eae61f0f95c3b66376a25635241fdJohannes Obermayr						      AVAIL_RING(chan)))
353bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			WAIT_RING(chan, PUSHBUF_DWORDS);
354bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
355bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BATCH_BEGIN(nvgl_primitive(prims[i].mode));
356bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
357bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		for (; start < end; start++) {
358bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			j = prims[i].basevertex +
359bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez				extract(&render->ib, 0, start);
360bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
3619d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez			FOR_EACH_BOUND_ATTR(render, k, attr)
3629d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez				EMIT_IMM(ctx, &render->attrs[attr], j);
363bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		}
364bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
365bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		BATCH_END();
366bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	}
367bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
368bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
369bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* draw_prims entry point when we're doing hw-tnl. */
370bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
371bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void
37257382e71ef892a36ca2171fe8758aba6c9c885e6Francisco JerezTAG(vbo_render_prims)(struct gl_context *ctx,
37357382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez		      const struct gl_client_array **arrays,
374bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		      const struct _mesa_prim *prims, GLuint nr_prims,
375bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		      const struct _mesa_index_buffer *ib,
376bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		      GLboolean index_bounds_valid,
377bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		      GLuint min_index, GLuint max_index)
378bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{
379bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	struct nouveau_render_state *render = to_render_state(ctx);
380bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
381bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (!index_bounds_valid)
382bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
383bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
384bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	vbo_choose_render_mode(ctx, arrays);
385bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	vbo_choose_attrs(ctx, arrays);
386bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
387bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (vbo_maybe_split(ctx, arrays, prims, nr_prims, ib, min_index,
388bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			    max_index))
389bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		return;
390bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
391bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	vbo_init_arrays(ctx, ib, arrays);
392bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
393bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	if (render->mode == VBO)
394bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_draw_vbo(ctx, arrays, prims, nr_prims, ib, min_index,
395bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			     max_index);
396bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	else
397bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez		vbo_draw_imm(ctx, arrays, prims, nr_prims, ib, min_index,
398bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez			     max_index);
399bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez
400bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez	vbo_deinit_arrays(ctx, ib, arrays);
401bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez}
402