1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 2009-2010 Francisco Jerez.
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a copy of this software and associated documentation files (the
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sublicense, and/or sell copies of the Software, and to
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * portions of the Software.
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tnl/t_context.h"
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tnl/t_pipeline.h"
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tnl/t_vertex.h"
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SWTNL_VBO_SIZE 65536
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic enum tnl_attr_format
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswtnl_get_format(int type, int fields) {
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (type) {
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case GL_FLOAT:
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		switch (fields){
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case 1:
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return EMIT_1F;
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case 2:
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return EMIT_2F;
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case 3:
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return EMIT_3F;
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case 4:
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return EMIT_4F;
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		default:
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			assert(0);
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case GL_UNSIGNED_BYTE:
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		switch (fields) {
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case 4:
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return EMIT_4UB_4F_RGBA;
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		default:
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			assert(0);
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	default:
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		assert(0);
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct swtnl_attr_info {
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int type;
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int fields;
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} swtnl_attrs[VERT_ATTRIB_MAX] = {
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	[VERT_ATTRIB_POS] = {
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		.type = GL_FLOAT,
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		.fields = 4,
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	},
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	[VERT_ATTRIB_NORMAL] = {
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		.type = GL_FLOAT,
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		.fields = -1,
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	},
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	[VERT_ATTRIB_COLOR0] = {
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		.type = GL_UNSIGNED_BYTE,
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		.fields = 4,
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	},
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	[VERT_ATTRIB_COLOR1] = {
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		.type = GL_UNSIGNED_BYTE,
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		.fields = 4,
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	},
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	[VERT_ATTRIB_FOG] = {
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		.type = GL_FLOAT,
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		.fields = 1,
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	},
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	[VERT_ATTRIB_TEX0] = {
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		.type = GL_FLOAT,
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		.fields = -1,
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	},
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	[VERT_ATTRIB_TEX1] = {
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		.type = GL_FLOAT,
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		.fields = -1,
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	},
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	[VERT_ATTRIB_TEX2] = {
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		.type = GL_FLOAT,
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		.fields = -1,
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	},
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	[VERT_ATTRIB_TEX3] = {
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		.type = GL_FLOAT,
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		.fields = -1,
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	},
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswtnl_choose_attrs(struct gl_context *ctx)
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct nouveau_render_state *render = to_render_state(ctx);
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	TNLcontext *tnl = TNL_CONTEXT(ctx);
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct tnl_clipspace *vtx = &tnl->clipspace;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	static struct tnl_attr_map map[NUM_VERTEX_ATTRS];
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int fields, attr, i, n = 0;
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	render->mode = VBO;
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	render->attr_count = NUM_VERTEX_ATTRS;
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* We always want non Ndc coords format */
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	tnl->vb.AttribPtr[VERT_ATTRIB_POS] = tnl->vb.ClipPtr;
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (i = 0; i < VERT_ATTRIB_MAX; i++) {
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct nouveau_attr_info *ha = &TAG(vertex_attrs)[i];
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct swtnl_attr_info *sa = &swtnl_attrs[i];
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct nouveau_array *a = &render->attrs[i];
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (!sa->fields)
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			continue; /* Unsupported attribute. */
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (tnl->render_inputs_bitset & BITFIELD64_BIT(i)) {
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			if (sa->fields > 0)
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				fields = sa->fields;
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			else
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				fields = tnl->vb.AttribPtr[i]->size;
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			map[n++] = (struct tnl_attr_map) {
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				.attrib = i,
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				.format = swtnl_get_format(sa->type, fields),
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			};
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			render->map[ha->vbo_index] = i;
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			a->attr = i;
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			a->fields = fields;
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			a->type = sa->type;
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	_tnl_install_attrs(ctx, map, n, NULL, 0);
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	FOR_EACH_BOUND_ATTR(render, i, attr)
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		render->attrs[attr].stride = vtx->vertex_size;
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	TAG(render_set_format)(ctx);
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswtnl_alloc_vertices(struct gl_context *ctx)
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct nouveau_swtnl_state *swtnl = &to_render_state(ctx)->swtnl;
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	nouveau_bo_ref(NULL, &swtnl->vbo);
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	swtnl->buf = nouveau_get_scratch(ctx, SWTNL_VBO_SIZE, &swtnl->vbo,
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					 &swtnl->offset);
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	swtnl->vertex_count = 0;
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswtnl_bind_vertices(struct gl_context *ctx)
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct nouveau_render_state *render = to_render_state(ctx);
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct nouveau_swtnl_state *swtnl = &render->swtnl;
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct tnl_clipspace *vtx = &TNL_CONTEXT(ctx)->clipspace;
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int i;
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (i = 0; i < vtx->attr_count; i++) {
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct tnl_clipspace_attr *ta = &vtx->attr[i];
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct nouveau_array *a = &render->attrs[ta->attrib];
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		nouveau_bo_ref(swtnl->vbo, &a->bo);
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		a->offset = swtnl->offset + ta->vertoffset;
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	TAG(render_bind_vertices)(ctx);
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswtnl_unbind_vertices(struct gl_context *ctx)
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct nouveau_render_state *render = to_render_state(ctx);
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int i, attr;
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	TAG(render_release_vertices)(ctx);
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	FOR_EACH_BOUND_ATTR(render, i, attr) {
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		nouveau_bo_ref(NULL, &render->attrs[attr].bo);
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		render->map[i] = -1;
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	render->attr_count = 0;
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswtnl_flush_vertices(struct gl_context *ctx)
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct nouveau_pushbuf *push = context_push(ctx);
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct nouveau_swtnl_state *swtnl = &to_render_state(ctx)->swtnl;
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned npush, start = 0, count = swtnl->vertex_count;
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	RENDER_LOCALS(ctx);
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	swtnl_bind_vertices(ctx);
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	while (count) {
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		npush = get_max_vertices(ctx, NULL, PUSH_AVAIL(push));
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		npush = MIN2(npush / 12 * 12, count);
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		count -= npush;
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (!npush) {
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			PUSH_KICK(push);
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			continue;
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		BATCH_BEGIN(nvgl_primitive(swtnl->primitive));
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		EMIT_VBO(L, ctx, start, 0, npush);
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		BATCH_END();
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		PUSH_KICK(push);
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	swtnl_alloc_vertices(ctx);
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* TnL renderer entry points */
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswtnl_start(struct gl_context *ctx)
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	swtnl_choose_attrs(ctx);
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswtnl_finish(struct gl_context *ctx)
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	swtnl_flush_vertices(ctx);
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	swtnl_unbind_vertices(ctx);
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswtnl_primitive(struct gl_context *ctx, GLenum mode)
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswtnl_reset_stipple(struct gl_context *ctx)
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Primitive rendering */
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define BEGIN_PRIMITIVE(p, n)						\
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct nouveau_swtnl_state *swtnl = &to_render_state(ctx)->swtnl; \
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int vertex_len = TNL_CONTEXT(ctx)->clipspace.vertex_size;	\
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org									\
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (swtnl->vertex_count + (n) > SWTNL_VBO_SIZE/vertex_len	\
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    || (swtnl->vertex_count && swtnl->primitive != p))		\
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		swtnl_flush_vertices(ctx);				\
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org									\
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	swtnl->primitive = p;
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define OUT_VERTEX(i) do {						\
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		memcpy(swtnl->buf + swtnl->vertex_count * vertex_len,	\
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       _tnl_get_vertex(ctx, (i)), vertex_len);		\
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		swtnl->vertex_count++;					\
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} while (0)
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswtnl_points(struct gl_context *ctx, GLuint first, GLuint last)
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int i, count;
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	while (first < last) {
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		BEGIN_PRIMITIVE(GL_POINTS, last - first);
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		count = MIN2(SWTNL_VBO_SIZE / vertex_len, last - first);
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for (i = 0; i < count; i++)
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			OUT_VERTEX(first + i);
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		first += count;
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswtnl_line(struct gl_context *ctx, GLuint v1, GLuint v2)
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	BEGIN_PRIMITIVE(GL_LINES, 2);
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	OUT_VERTEX(v1);
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	OUT_VERTEX(v2);
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswtnl_triangle(struct gl_context *ctx, GLuint v1, GLuint v2, GLuint v3)
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	BEGIN_PRIMITIVE(GL_TRIANGLES, 3);
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	OUT_VERTEX(v1);
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	OUT_VERTEX(v2);
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	OUT_VERTEX(v3);
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswtnl_quad(struct gl_context *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4)
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	BEGIN_PRIMITIVE(GL_QUADS, 4);
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	OUT_VERTEX(v1);
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	OUT_VERTEX(v2);
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	OUT_VERTEX(v3);
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	OUT_VERTEX(v4);
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* TnL initialization. */
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgTAG(swtnl_init)(struct gl_context *ctx)
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	TNLcontext *tnl = TNL_CONTEXT(ctx);
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	tnl->Driver.RunPipeline = _tnl_run_pipeline;
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	tnl->Driver.Render.Interp = _tnl_interp;
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	tnl->Driver.Render.CopyPV = _tnl_copy_pv;
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine;
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	tnl->Driver.Render.Start = swtnl_start;
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	tnl->Driver.Render.Finish = swtnl_finish;
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	tnl->Driver.Render.PrimitiveNotify = swtnl_primitive;
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	tnl->Driver.Render.ResetLineStipple = swtnl_reset_stipple;
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	tnl->Driver.Render.Points = swtnl_points;
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	tnl->Driver.Render.Line = swtnl_line;
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	tnl->Driver.Render.Triangle = swtnl_triangle;
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	tnl->Driver.Render.Quad = swtnl_quad;
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	_tnl_init_vertices(ctx, tnl->vb.Size,
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   NUM_VERTEX_ATTRS * 4 * sizeof(GLfloat));
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	_tnl_need_projected_coords(ctx, GL_FALSE);
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	_tnl_allow_vertex_fog(ctx, GL_FALSE);
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	_tnl_wakeup(ctx);
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	swtnl_alloc_vertices(ctx);
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgTAG(swtnl_destroy)(struct gl_context *ctx)
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	nouveau_bo_ref(NULL, &to_render_state(ctx)->swtnl.vbo);
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
351