nouveau: Add notifier support functions
[mesa.git] / src / mesa / tnl / t_array_import.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5.1
4 *
5 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Keith Whitwell <keith@tungstengraphics.com>
26 */
27
28 #include "glheader.h"
29 #include "context.h"
30 #include "macros.h"
31 #include "imports.h"
32 #include "state.h"
33 #include "mtypes.h"
34
35 #include "array_cache/acache.h"
36
37 #include "t_array_import.h"
38 #include "t_context.h"
39
40
41 /**
42 * XXX writable and stride are always false in these functions...
43 */
44 static void _tnl_import_vertex( GLcontext *ctx,
45 GLboolean writable,
46 GLboolean stride )
47 {
48 struct gl_client_array *tmp;
49 GLboolean is_writable = 0;
50 struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
51 const GLubyte *data;
52
53 tmp = _ac_import_vertex(ctx,
54 GL_FLOAT,
55 stride ? 4*sizeof(GLfloat) : 0,
56 0,
57 writable,
58 &is_writable);
59
60 data = tmp->Ptr;
61 inputs->Obj.data = (GLfloat (*)[4]) data;
62 inputs->Obj.start = (GLfloat *) data;
63 inputs->Obj.stride = tmp->StrideB;
64 inputs->Obj.size = tmp->Size;
65 }
66
67 static void _tnl_import_normal( GLcontext *ctx,
68 GLboolean writable,
69 GLboolean stride )
70 {
71 struct gl_client_array *tmp;
72 GLboolean is_writable = 0;
73 struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
74 const GLubyte *data;
75
76 tmp = _ac_import_normal(ctx, GL_FLOAT,
77 stride ? 3*sizeof(GLfloat) : 0, writable,
78 &is_writable);
79
80 data = tmp->Ptr;
81 inputs->Normal.data = (GLfloat (*)[4]) data;
82 inputs->Normal.start = (GLfloat *) data;
83 inputs->Normal.stride = tmp->StrideB;
84 inputs->Normal.size = 3;
85 }
86
87
88 static void _tnl_import_color( GLcontext *ctx,
89 GLboolean writable,
90 GLboolean stride )
91 {
92 struct gl_client_array *tmp;
93 GLboolean is_writable = 0;
94 struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
95 const GLubyte *data;
96
97 tmp = _ac_import_color(ctx,
98 GL_FLOAT,
99 stride ? 4*sizeof(GLfloat) : 0,
100 4,
101 writable,
102 &is_writable);
103
104 data = tmp->Ptr;
105 inputs->Color.data = (GLfloat (*)[4]) data;
106 inputs->Color.start = (GLfloat *) data;
107 inputs->Color.stride = tmp->StrideB;
108 inputs->Color.size = tmp->Size;
109 }
110
111
112 static void _tnl_import_secondarycolor( GLcontext *ctx,
113 GLboolean writable,
114 GLboolean stride )
115 {
116 struct gl_client_array *tmp;
117 GLboolean is_writable = 0;
118 struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
119 const GLubyte *data;
120
121 tmp = _ac_import_secondarycolor(ctx,
122 GL_FLOAT,
123 stride ? 4*sizeof(GLfloat) : 0,
124 4,
125 writable,
126 &is_writable);
127
128 data = tmp->Ptr;
129 inputs->SecondaryColor.data = (GLfloat (*)[4]) data;
130 inputs->SecondaryColor.start = (GLfloat *) data;
131 inputs->SecondaryColor.stride = tmp->StrideB;
132 inputs->SecondaryColor.size = tmp->Size;
133 }
134
135 static void _tnl_import_fogcoord( GLcontext *ctx,
136 GLboolean writable,
137 GLboolean stride )
138 {
139 struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
140 struct gl_client_array *tmp;
141 GLboolean is_writable = 0;
142 const GLubyte *data;
143
144 tmp = _ac_import_fogcoord(ctx, GL_FLOAT,
145 stride ? sizeof(GLfloat) : 0, writable,
146 &is_writable);
147
148 data = tmp->Ptr;
149 inputs->FogCoord.data = (GLfloat (*)[4]) data;
150 inputs->FogCoord.start = (GLfloat *) data;
151 inputs->FogCoord.stride = tmp->StrideB;
152 }
153
154 static void _tnl_import_index( GLcontext *ctx,
155 GLboolean writable,
156 GLboolean stride )
157 {
158 struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
159 struct gl_client_array *tmp;
160 GLboolean is_writable = 0;
161 const GLubyte *data;
162
163 tmp = _ac_import_index(ctx, GL_FLOAT,
164 stride ? sizeof(GLfloat) : 0, writable,
165 &is_writable);
166
167 data = tmp->Ptr;
168 inputs->Index.data = (GLfloat (*)[4]) data;
169 inputs->Index.start = (GLfloat *) data;
170 inputs->Index.stride = tmp->StrideB;
171 }
172
173
174 static void _tnl_import_texcoord( GLcontext *ctx,
175 GLuint unit,
176 GLboolean writable,
177 GLboolean stride )
178 {
179 struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
180 struct gl_client_array *tmp;
181 GLboolean is_writable = 0;
182 const GLubyte *data;
183
184 tmp = _ac_import_texcoord(ctx, unit, GL_FLOAT,
185 stride ? 4 * sizeof(GLfloat) : 0,
186 0,
187 writable,
188 &is_writable);
189
190 data = tmp->Ptr;
191 inputs->TexCoord[unit].data = (GLfloat (*)[4]) data;
192 inputs->TexCoord[unit].start = (GLfloat *) data;
193 inputs->TexCoord[unit].stride = tmp->StrideB;
194 inputs->TexCoord[unit].size = tmp->Size;
195 }
196
197
198 static void _tnl_import_edgeflag( GLcontext *ctx,
199 GLboolean writable,
200 GLboolean stride )
201 {
202 struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
203 struct gl_client_array *tmp;
204 GLboolean is_writable = 0;
205 const GLubyte *data;
206 (void) writable; (void) stride;
207
208 tmp = _ac_import_edgeflag(ctx, GL_UNSIGNED_BYTE,
209 sizeof(GLubyte),
210 0,
211 &is_writable);
212
213 data = tmp->Ptr;
214 inputs->EdgeFlag = (GLubyte *) data;
215 }
216
217
218
219 static void _tnl_import_attrib( GLcontext *ctx,
220 GLuint index,
221 GLboolean writable,
222 GLboolean stride )
223 {
224 struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
225 struct gl_client_array *tmp;
226 GLboolean is_writable = 0;
227 const GLubyte *data;
228
229 ASSERT(index < MAX_VERTEX_PROGRAM_ATTRIBS);
230
231 tmp = _ac_import_attrib(ctx, index, GL_FLOAT,
232 stride ? 4 * sizeof(GLfloat) : 0,
233 4, /* want GLfloat[4] */
234 writable,
235 &is_writable);
236
237 data = tmp->Ptr;
238 inputs->Attribs[index].data = (GLfloat (*)[4]) data;
239 inputs->Attribs[index].start = (GLfloat *) data;
240 inputs->Attribs[index].stride = tmp->StrideB;
241 inputs->Attribs[index].size = tmp->Size;
242 }
243
244
245 static void _tnl_constant_attrib( TNLcontext *tnl,
246 struct tnl_vertex_arrays *tmp,
247 GLuint i )
248 {
249 tmp->Attribs[i].count = 1;
250 tmp->Attribs[i].data = (GLfloat (*)[4]) tnl->vtx.current[i];
251 tmp->Attribs[i].start = tnl->vtx.current[i];
252 tmp->Attribs[i].size = 4;
253 tmp->Attribs[i].stride = 0;
254 tnl->vb.AttribPtr[i] = &tmp->Attribs[i];
255 }
256
257
258
259 void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLint end)
260 {
261 TNLcontext *tnl = TNL_CONTEXT(ctx);
262 struct vertex_buffer *VB = &tnl->vb;
263 struct tnl_vertex_arrays *tmp = &tnl->array_inputs;
264 const struct gl_vertex_program *program
265 = ctx->VertexProgram._Enabled ? ctx->VertexProgram.Current : NULL;
266 GLuint i, index;
267
268 VB->Count = end - start;
269 VB->Elts = NULL;
270
271 _ac_import_range( ctx, start, end );
272
273 /* Note that the generic attribute arrays are treated differently
274 * depending on whether an NV or ARB vertex program is enabled
275 * (corresponding to aliasing vs. non-aliasing behaviour).
276 * Generic array 0 always aliases vertex position.
277 */
278 for (index = 0; index < VERT_ATTRIB_MAX; index++) {
279 if (ctx->VertexProgram._Enabled
280 && (program->IsNVProgram || index == 0)
281 && ctx->Array.ArrayObj->VertexAttrib[index].Enabled) {
282 /* Use generic attribute array. If an NV vertex program is active,
283 * the generic arrays override the conventional attributes.
284 * Otherwise, if an ARB vertex program is active, we'll import the
285 * generic attributes without aliasing over conventional attribs
286 * (see below).
287 */
288 _tnl_import_attrib( ctx, index, GL_FALSE, GL_TRUE );
289 VB->AttribPtr[index] = &tmp->Attribs[index];
290 }
291 /* use conventional arrays... */
292 else if (index == VERT_ATTRIB_POS) {
293 _tnl_import_vertex( ctx, GL_FALSE, GL_FALSE );
294 tmp->Obj.count = VB->Count;
295 VB->AttribPtr[_TNL_ATTRIB_POS] = &tmp->Obj;
296 }
297 else if (index == VERT_ATTRIB_NORMAL) {
298 _tnl_import_normal( ctx, GL_FALSE, GL_FALSE );
299 tmp->Normal.count = VB->Count;
300 VB->AttribPtr[_TNL_ATTRIB_NORMAL] = &tmp->Normal;
301 }
302 else if (index == VERT_ATTRIB_COLOR0) {
303 _tnl_import_color( ctx, GL_FALSE, GL_FALSE );
304 tmp->Color.count = VB->Count;
305 VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &tmp->Color;
306 }
307 else if (index == VERT_ATTRIB_COLOR1) {
308 _tnl_import_secondarycolor( ctx, GL_FALSE, GL_FALSE );
309 tmp->SecondaryColor.count = VB->Count;
310 VB->AttribPtr[_TNL_ATTRIB_COLOR1] = &tmp->SecondaryColor;
311 }
312 else if (index == VERT_ATTRIB_FOG) {
313 _tnl_import_fogcoord( ctx, GL_FALSE, GL_FALSE );
314 tmp->FogCoord.count = VB->Count;
315 VB->AttribPtr[_TNL_ATTRIB_FOG] = &tmp->FogCoord;
316 }
317 else if (index == VERT_ATTRIB_COLOR_INDEX) {
318 _tnl_import_index( ctx, GL_FALSE, GL_FALSE );
319 tmp->Index.count = VB->Count;
320 VB->AttribPtr[_TNL_ATTRIB_COLOR_INDEX] = &tmp->Index;
321 }
322 else if (index >= VERT_ATTRIB_TEX0 && index <= VERT_ATTRIB_TEX7) {
323 i = index - VERT_ATTRIB_TEX0;
324 _tnl_import_texcoord( ctx, i, GL_FALSE, GL_FALSE );
325 tmp->TexCoord[i].count = VB->Count;
326 VB->AttribPtr[index] = &tmp->TexCoord[i];
327 }
328 else if (index >= VERT_ATTRIB_GENERIC1 &&
329 index <= VERT_ATTRIB_GENERIC15) {
330 const GLuint arrayIndex = index - VERT_ATTRIB_GENERIC0;
331 if (program && !program->IsNVProgram &&
332 ctx->Array.ArrayObj->VertexAttrib[arrayIndex].Enabled) {
333 /* GL_ARB_vertex_program: bind a generic attribute array */
334 _tnl_import_attrib(ctx, arrayIndex, GL_FALSE, GL_TRUE);
335 VB->AttribPtr[index] = &tmp->Attribs[arrayIndex];
336 }
337 else {
338 _tnl_constant_attrib(tnl, tmp, index);
339 }
340 }
341 else {
342 _tnl_constant_attrib(tnl, tmp, index);
343 }
344 assert(VB->AttribPtr[index]);
345 assert(VB->AttribPtr[index]->size);
346 }
347
348 /* odd-ball vertex attributes */
349 {
350 _tnl_import_edgeflag( ctx, GL_TRUE, sizeof(GLboolean) );
351 VB->EdgeFlag = (GLboolean *) tmp->EdgeFlag;
352 }
353
354 /* These are constant & could be precalculated:
355 */
356 for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
357 _tnl_constant_attrib(tnl, tmp, i);
358 }
359
360
361 /* Legacy pointers -- remove one day.
362 */
363 VB->ObjPtr = VB->AttribPtr[_TNL_ATTRIB_POS];
364 VB->NormalPtr = VB->AttribPtr[_TNL_ATTRIB_NORMAL];
365 VB->ColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR0];
366 VB->ColorPtr[1] = NULL;
367 VB->IndexPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR_INDEX];
368 VB->IndexPtr[1] = NULL;
369 VB->SecondaryColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR1];
370 VB->SecondaryColorPtr[1] = NULL;
371 VB->FogCoordPtr = VB->AttribPtr[_TNL_ATTRIB_FOG];
372
373 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
374 VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i];
375 }
376 }