Killed mmath.[ch]. Moved low-level functions/assembly code into imports.[ch]
[mesa.git] / src / mesa / tnl / t_array_import.c
1 /* $Id: t_array_import.c,v 1.28 2003/03/01 01:50:26 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 5.1
6 *
7 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 * Authors:
27 * Keith Whitwell <keith@tungstengraphics.com>
28 */
29
30 #include "glheader.h"
31 #include "context.h"
32 #include "macros.h"
33 #include "imports.h"
34 #include "state.h"
35 #include "mtypes.h"
36
37 #include "array_cache/acache.h"
38 #include "math/m_translate.h"
39
40 #include "t_array_import.h"
41 #include "t_context.h"
42 #include "t_imm_debug.h"
43
44
45 static void _tnl_import_vertex( GLcontext *ctx,
46 GLboolean writeable,
47 GLboolean stride )
48 {
49 struct gl_client_array *tmp;
50 GLboolean is_writeable = 0;
51 struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
52
53 tmp = _ac_import_vertex(ctx,
54 GL_FLOAT,
55 stride ? 4*sizeof(GLfloat) : 0,
56 0,
57 writeable,
58 &is_writeable);
59
60 inputs->Obj.data = (GLfloat (*)[4]) tmp->Ptr;
61 inputs->Obj.start = (GLfloat *) tmp->Ptr;
62 inputs->Obj.stride = tmp->StrideB;
63 inputs->Obj.size = tmp->Size;
64 inputs->Obj.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
65 if (inputs->Obj.stride != 4*sizeof(GLfloat))
66 inputs->Obj.flags |= VEC_BAD_STRIDE;
67 if (!is_writeable)
68 inputs->Obj.flags |= VEC_NOT_WRITEABLE;
69 }
70
71 static void _tnl_import_normal( GLcontext *ctx,
72 GLboolean writeable,
73 GLboolean stride )
74 {
75 struct gl_client_array *tmp;
76 GLboolean is_writeable = 0;
77 struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
78
79 tmp = _ac_import_normal(ctx, GL_FLOAT,
80 stride ? 3*sizeof(GLfloat) : 0, writeable,
81 &is_writeable);
82
83 inputs->Normal.data = (GLfloat (*)[4]) tmp->Ptr;
84 inputs->Normal.start = (GLfloat *) tmp->Ptr;
85 inputs->Normal.stride = tmp->StrideB;
86 inputs->Normal.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
87 if (inputs->Normal.stride != 3*sizeof(GLfloat))
88 inputs->Normal.flags |= VEC_BAD_STRIDE;
89 if (!is_writeable)
90 inputs->Normal.flags |= VEC_NOT_WRITEABLE;
91 }
92
93
94 static void _tnl_import_color( GLcontext *ctx,
95 GLenum type,
96 GLboolean writeable,
97 GLboolean stride )
98 {
99 struct gl_client_array *tmp;
100 GLboolean is_writeable = 0;
101 struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
102
103 tmp = _ac_import_color(ctx,
104 type,
105 stride ? 4*sizeof(GLfloat) : 0,
106 4,
107 writeable,
108 &is_writeable);
109
110 inputs->Color = *tmp;
111 }
112
113
114 static void _tnl_import_secondarycolor( GLcontext *ctx,
115 GLenum type,
116 GLboolean writeable,
117 GLboolean stride )
118 {
119 struct gl_client_array *tmp;
120 GLboolean is_writeable = 0;
121 struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
122
123 tmp = _ac_import_secondarycolor(ctx,
124 type,
125 stride ? 4*sizeof(GLfloat) : 0,
126 4,
127 writeable,
128 &is_writeable);
129
130 inputs->SecondaryColor = *tmp;
131 }
132
133 static void _tnl_import_fogcoord( GLcontext *ctx,
134 GLboolean writeable,
135 GLboolean stride )
136 {
137 struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
138 struct gl_client_array *tmp;
139 GLboolean is_writeable = 0;
140
141 tmp = _ac_import_fogcoord(ctx, GL_FLOAT,
142 stride ? sizeof(GLfloat) : 0, writeable,
143 &is_writeable);
144
145 inputs->FogCoord.data = (GLfloat (*)[4]) tmp->Ptr;
146 inputs->FogCoord.start = (GLfloat *) tmp->Ptr;
147 inputs->FogCoord.stride = tmp->StrideB;
148 inputs->FogCoord.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
149 if (inputs->FogCoord.stride != sizeof(GLfloat))
150 inputs->FogCoord.flags |= VEC_BAD_STRIDE;
151 if (!is_writeable)
152 inputs->FogCoord.flags |= VEC_NOT_WRITEABLE;
153 }
154
155 static void _tnl_import_index( GLcontext *ctx,
156 GLboolean writeable,
157 GLboolean stride )
158 {
159 struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
160 struct gl_client_array *tmp;
161 GLboolean is_writeable = 0;
162
163 tmp = _ac_import_index(ctx, GL_UNSIGNED_INT,
164 stride ? sizeof(GLuint) : 0, writeable,
165 &is_writeable);
166
167 inputs->Index.data = (GLuint *) tmp->Ptr;
168 inputs->Index.start = (GLuint *) tmp->Ptr;
169 inputs->Index.stride = tmp->StrideB;
170 inputs->Index.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
171 if (inputs->Index.stride != sizeof(GLuint))
172 inputs->Index.flags |= VEC_BAD_STRIDE;
173 if (!is_writeable)
174 inputs->Index.flags |= VEC_NOT_WRITEABLE;
175 }
176
177
178 static void _tnl_import_texcoord( GLcontext *ctx,
179 GLuint unit,
180 GLboolean writeable,
181 GLboolean stride )
182 {
183 struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
184 struct gl_client_array *tmp;
185 GLboolean is_writeable = 0;
186
187 tmp = _ac_import_texcoord(ctx, unit, GL_FLOAT,
188 stride ? 4 * sizeof(GLfloat) : 0,
189 0,
190 writeable,
191 &is_writeable);
192
193 inputs->TexCoord[unit].data = (GLfloat (*)[4]) tmp->Ptr;
194 inputs->TexCoord[unit].start = (GLfloat *) tmp->Ptr;
195 inputs->TexCoord[unit].stride = tmp->StrideB;
196 inputs->TexCoord[unit].size = tmp->Size;
197 inputs->TexCoord[unit].flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
198 if (inputs->TexCoord[unit].stride != 4*sizeof(GLfloat))
199 inputs->TexCoord[unit].flags |= VEC_BAD_STRIDE;
200 if (!is_writeable)
201 inputs->TexCoord[unit].flags |= VEC_NOT_WRITEABLE;
202 }
203
204
205 static void _tnl_import_edgeflag( GLcontext *ctx,
206 GLboolean writeable,
207 GLboolean stride )
208 {
209 struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
210 struct gl_client_array *tmp;
211 GLboolean is_writeable = 0;
212
213 tmp = _ac_import_edgeflag(ctx, GL_UNSIGNED_BYTE,
214 stride ? sizeof(GLubyte) : 0,
215 0,
216 &is_writeable);
217
218 inputs->EdgeFlag.data = (GLubyte *) tmp->Ptr;
219 inputs->EdgeFlag.start = (GLubyte *) tmp->Ptr;
220 inputs->EdgeFlag.stride = tmp->StrideB;
221 inputs->EdgeFlag.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
222 if (inputs->EdgeFlag.stride != sizeof(GLubyte))
223 inputs->EdgeFlag.flags |= VEC_BAD_STRIDE;
224 if (!is_writeable)
225 inputs->EdgeFlag.flags |= VEC_NOT_WRITEABLE;
226 }
227
228
229
230 static void _tnl_import_attrib( GLcontext *ctx,
231 GLuint index,
232 GLboolean writeable,
233 GLboolean stride )
234 {
235 struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
236 struct gl_client_array *tmp;
237 GLboolean is_writeable = 0;
238
239 tmp = _ac_import_attrib(ctx, index, GL_FLOAT,
240 stride ? 4 * sizeof(GLfloat) : 0,
241 4, /* want GLfloat[4] */
242 writeable,
243 &is_writeable);
244
245 inputs->Attribs[index].data = (GLfloat (*)[4]) tmp->Ptr;
246 inputs->Attribs[index].start = (GLfloat *) tmp->Ptr;
247 inputs->Attribs[index].stride = tmp->StrideB;
248 inputs->Attribs[index].size = tmp->Size;
249 inputs->Attribs[index].flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
250 if (inputs->Attribs[index].stride != 4 * sizeof(GLfloat))
251 inputs->Attribs[index].flags |= VEC_BAD_STRIDE;
252 if (!is_writeable)
253 inputs->Attribs[index].flags |= VEC_NOT_WRITEABLE;
254 }
255
256
257
258 /**
259 * Callback for VB stages that need to improve the quality of arrays
260 * bound to the VB. This is only necessary for client arrays which
261 * have not been transformed at any point in the pipeline.
262 * \param required - bitmask of VERT_*_BIT flags
263 * \param flags - bitmask of VEC_* flags (ex: VEC_NOT_WRITABLE)
264 */
265 static void _tnl_upgrade_client_data( GLcontext *ctx,
266 GLuint required,
267 GLuint flags )
268 {
269 GLuint i;
270 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
271 GLboolean writeable = (flags & VEC_NOT_WRITEABLE) != 0;
272 GLboolean stride = (flags & VEC_BAD_STRIDE) != 0;
273 struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
274 GLuint ca_flags = 0;
275 (void) inputs;
276
277 if (writeable || stride) ca_flags |= CA_CLIENT_DATA;
278
279 if ((required & VERT_BIT_CLIP) && VB->ClipPtr == VB->ObjPtr)
280 required |= VERT_BIT_POS;
281
282 /* _tnl_print_vert_flags("_tnl_upgrade_client_data", required); */
283
284 if ((required & VERT_BIT_POS) && (VB->ObjPtr->flags & flags)) {
285 ASSERT(VB->ObjPtr == &inputs->Obj);
286 _tnl_import_vertex( ctx, writeable, stride );
287 VB->importable_data &= ~(VERT_BIT_POS|VERT_BIT_CLIP);
288 }
289
290 if ((required & VERT_BIT_NORMAL) && (VB->NormalPtr->flags & flags)) {
291 ASSERT(VB->NormalPtr == &inputs->Normal);
292 _tnl_import_normal( ctx, writeable, stride );
293 VB->importable_data &= ~VERT_BIT_NORMAL;
294 }
295
296 if ((required & VERT_BIT_COLOR0) && (VB->ColorPtr[0]->Flags & ca_flags)) {
297 ASSERT(VB->ColorPtr[0] == &inputs->Color);
298 _tnl_import_color( ctx, GL_FLOAT, writeable, stride );
299 VB->importable_data &= ~VERT_BIT_COLOR0;
300 }
301
302 if ((required & VERT_BIT_COLOR1) &&
303 (VB->SecondaryColorPtr[0]->Flags & ca_flags)) {
304 ASSERT(VB->SecondaryColorPtr[0] == &inputs->SecondaryColor);
305 _tnl_import_secondarycolor( ctx, GL_FLOAT, writeable, stride );
306 VB->importable_data &= ~VERT_BIT_COLOR1;
307 }
308
309 if ((required & VERT_BIT_FOG)
310 && (VB->FogCoordPtr->flags & flags)) {
311 ASSERT(VB->FogCoordPtr == &inputs->FogCoord);
312 _tnl_import_fogcoord( ctx, writeable, stride );
313 VB->importable_data &= ~VERT_BIT_FOG;
314 }
315
316 if ((required & VERT_BIT_INDEX) && (VB->IndexPtr[0]->flags & flags)) {
317 ASSERT(VB->IndexPtr[0] == &inputs->Index);
318 _tnl_import_index( ctx, writeable, stride );
319 VB->importable_data &= ~VERT_BIT_INDEX;
320 }
321
322 if (required & VERT_BITS_TEX_ANY)
323 for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
324 if ((required & VERT_BIT_TEX(i)) && (VB->TexCoordPtr[i]->flags & flags)) {
325 ASSERT(VB->TexCoordPtr[i] == &inputs->TexCoord[i]);
326 _tnl_import_texcoord( ctx, i, writeable, stride );
327 VB->importable_data &= ~VERT_BIT_TEX(i);
328 }
329
330 /* XXX not sure what to do here for vertex program arrays */
331 }
332
333
334
335 void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLsizei count )
336 {
337 TNLcontext *tnl = TNL_CONTEXT(ctx);
338 struct vertex_buffer *VB = &tnl->vb;
339 GLuint inputs = tnl->pipeline.inputs;
340 struct vertex_arrays *tmp = &tnl->array_inputs;
341
342 /* _mesa_debug(ctx, "%s %d..%d // %d..%d\n", __FUNCTION__, */
343 /* start, count, ctx->Array.LockFirst, ctx->Array.LockCount); */
344 /* _tnl_print_vert_flags(" inputs", inputs); */
345 /* _tnl_print_vert_flags(" _Enabled", ctx->Array._Enabled); */
346 /* _tnl_print_vert_flags(" importable", inputs & VERT_BITS_FIXUP); */
347
348 VB->Count = count - start;
349 VB->FirstClipped = VB->Count;
350 VB->Elts = NULL;
351 VB->MaterialMask = NULL;
352 VB->Material = NULL;
353 VB->Flag = NULL;
354 VB->Primitive = tnl->tmp_primitive;
355 VB->PrimitiveLength = tnl->tmp_primitive_length;
356 VB->import_data = _tnl_upgrade_client_data;
357 VB->importable_data = inputs & VERT_BITS_FIXUP;
358
359 if (ctx->Array.LockCount) {
360 ASSERT(start == (GLint) ctx->Array.LockFirst);
361 ASSERT(count == (GLint) ctx->Array.LockCount);
362 }
363
364 _ac_import_range( ctx, start, count );
365
366 if (inputs & VERT_BIT_POS) {
367 _tnl_import_vertex( ctx, 0, 0 );
368 tmp->Obj.count = VB->Count;
369 VB->ObjPtr = &tmp->Obj;
370 }
371
372 if (inputs & VERT_BIT_NORMAL) {
373 _tnl_import_normal( ctx, 0, 0 );
374 tmp->Normal.count = VB->Count;
375 VB->NormalPtr = &tmp->Normal;
376 }
377
378 if (inputs & VERT_BIT_COLOR0) {
379 _tnl_import_color( ctx, 0, 0, 0 );
380 VB->ColorPtr[0] = &tmp->Color;
381 VB->ColorPtr[1] = 0;
382 }
383
384 if (inputs & VERT_BITS_TEX_ANY) {
385 GLuint unit;
386 for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
387 if (inputs & VERT_BIT_TEX(unit)) {
388 _tnl_import_texcoord( ctx, unit, GL_FALSE, GL_FALSE );
389 tmp->TexCoord[unit].count = VB->Count;
390 VB->TexCoordPtr[unit] = &tmp->TexCoord[unit];
391 }
392 }
393 }
394
395 if (inputs & (VERT_BIT_INDEX | VERT_BIT_FOG |
396 VERT_BIT_EDGEFLAG | VERT_BIT_COLOR1)) {
397 if (inputs & VERT_BIT_INDEX) {
398 _tnl_import_index( ctx, 0, 0 );
399 tmp->Index.count = VB->Count;
400 VB->IndexPtr[0] = &tmp->Index;
401 VB->IndexPtr[1] = 0;
402 }
403
404 if (inputs & VERT_BIT_FOG) {
405 _tnl_import_fogcoord( ctx, 0, 0 );
406 tmp->FogCoord.count = VB->Count;
407 VB->FogCoordPtr = &tmp->FogCoord;
408 }
409
410 if (inputs & VERT_BIT_EDGEFLAG) {
411 _tnl_import_edgeflag( ctx, GL_TRUE, sizeof(GLboolean) );
412 VB->EdgeFlag = (GLboolean *) tmp->EdgeFlag.data;
413 }
414
415 if (inputs & VERT_BIT_COLOR1) {
416 _tnl_import_secondarycolor( ctx, 0, 0, 0 );
417 VB->SecondaryColorPtr[0] = &tmp->SecondaryColor;
418 VB->SecondaryColorPtr[1] = 0;
419 }
420 }
421
422 /* XXX not 100% sure this is finished. Keith should probably inspect. */
423 if (ctx->VertexProgram.Enabled) {
424 GLuint index;
425 for (index = 0; index < VERT_ATTRIB_MAX; index++) {
426 /* XXX check program->InputsRead to reduce work here */
427 _tnl_import_attrib( ctx, index, GL_FALSE, GL_TRUE );
428 VB->AttribPtr[index] = &tmp->Attribs[index];
429 }
430 }
431 }