Removed all RCS / CVS tags (Id, Header, Date, etc.) from everything.
[mesa.git] / src / mesa / math / m_vector.c
1
2 /*
3 * Mesa 3-D graphics library
4 * Version: 3.5
5 *
6 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 /*
27 * New (3.1) transformation code written by Keith Whitwell.
28 */
29
30
31 #include "glheader.h"
32 #include "imports.h"
33 #include "macros.h"
34 #include "imports.h"
35
36 #include "m_vector.h"
37
38
39
40 /*
41 * Given a vector [count][4] of floats, set all the [][elt] values
42 * to 0 (if elt = 0, 1, 2) or 1.0 (if elt = 3).
43 */
44 void _mesa_vector4f_clean_elem( GLvector4f *vec, GLuint count, GLuint elt )
45 {
46 static const GLubyte elem_bits[4] = {
47 VEC_DIRTY_0,
48 VEC_DIRTY_1,
49 VEC_DIRTY_2,
50 VEC_DIRTY_3
51 };
52 static const GLfloat clean[4] = { 0, 0, 0, 1 };
53 const GLfloat v = clean[elt];
54 GLfloat (*data)[4] = (GLfloat (*)[4])vec->start;
55 GLuint i;
56
57 for (i = 0 ; i < count ; i++)
58 data[i][elt] = v;
59
60 vec->flags &= ~elem_bits[elt];
61 }
62
63 static const GLubyte size_bits[5] = {
64 0,
65 VEC_SIZE_1,
66 VEC_SIZE_2,
67 VEC_SIZE_3,
68 VEC_SIZE_4,
69 };
70
71
72
73 /*
74 * Initialize GLvector objects.
75 * Input: v - the vector object to initialize.
76 * flags - bitwise-OR of VEC_* flags
77 * storage - pointer to storage for the vector's data
78 */
79
80
81 void _mesa_vector4f_init( GLvector4f *v, GLuint flags, GLfloat (*storage)[4] )
82 {
83 v->stride = 4 * sizeof(GLfloat);
84 v->size = 2; /* may change: 2-4 for vertices and 1-4 for texcoords */
85 v->data = storage;
86 v->start = (GLfloat *) storage;
87 v->count = 0;
88 v->flags = size_bits[4] | flags ;
89 }
90
91 void _mesa_vector3f_init( GLvector3f *v, GLuint flags, GLfloat (*storage)[3] )
92 {
93 v->stride = 3 * sizeof(GLfloat);
94 v->data = storage;
95 v->start = (GLfloat *) storage;
96 v->count = 0;
97 v->flags = flags ;
98 }
99
100 void _mesa_vector1f_init( GLvector1f *v, GLuint flags, GLfloat *storage )
101 {
102 v->stride = 1*sizeof(GLfloat);
103 v->data = storage;
104 v->start = (GLfloat *)storage;
105 v->count = 0;
106 v->flags = flags ;
107 }
108
109 void _mesa_vector4ub_init( GLvector4ub *v, GLuint flags, GLubyte (*storage)[4] )
110 {
111 v->stride = 4 * sizeof(GLubyte);
112 v->data = storage;
113 v->start = (GLubyte *) storage;
114 v->count = 0;
115 v->flags = flags ;
116 }
117
118 void _mesa_vector4chan_init( GLvector4chan *v, GLuint flags, GLchan (*storage)[4] )
119 {
120 v->stride = 4 * sizeof(GLchan);
121 v->data = storage;
122 v->start = (GLchan *) storage;
123 v->count = 0;
124 v->flags = flags ;
125 }
126
127 void _mesa_vector4us_init( GLvector4us *v, GLuint flags, GLushort (*storage)[4] )
128 {
129 v->stride = 4 * sizeof(GLushort);
130 v->data = storage;
131 v->start = (GLushort *) storage;
132 v->count = 0;
133 v->flags = flags ;
134 }
135
136 void _mesa_vector1ub_init( GLvector1ub *v, GLuint flags, GLubyte *storage )
137 {
138 v->stride = 1 * sizeof(GLubyte);
139 v->data = storage;
140 v->start = (GLubyte *) storage;
141 v->count = 0;
142 v->flags = flags ;
143 }
144
145 void _mesa_vector1ui_init( GLvector1ui *v, GLuint flags, GLuint *storage )
146 {
147 v->stride = 1 * sizeof(GLuint);
148 v->data = storage;
149 v->start = (GLuint *) storage;
150 v->count = 0;
151 v->flags = flags ;
152 }
153
154
155 /*
156 * Initialize GLvector objects and allocate storage.
157 * Input: v - the vector object
158 * sz - unused????
159 * flags - bitwise-OR of VEC_* flags
160 * count - number of elements to allocate in vector
161 * alignment - desired memory alignment for the data (in bytes)
162 */
163
164
165 void _mesa_vector4f_alloc( GLvector4f *v, GLuint flags, GLuint count,
166 GLuint alignment )
167 {
168 v->stride = 4 * sizeof(GLfloat);
169 v->size = 2;
170 v->storage = ALIGN_MALLOC( count * 4 * sizeof(GLfloat), alignment );
171 v->start = (GLfloat *) v->storage;
172 v->data = (GLfloat (*)[4]) v->storage;
173 v->count = 0;
174 v->flags = size_bits[4] | flags | VEC_MALLOC ;
175 }
176
177 void _mesa_vector3f_alloc( GLvector3f *v, GLuint flags, GLuint count,
178 GLuint alignment )
179 {
180 v->stride = 3 * sizeof(GLfloat);
181 v->storage = ALIGN_MALLOC( count * 3 * sizeof(GLfloat), alignment );
182 v->start = (GLfloat *) v->storage;
183 v->data = (GLfloat (*)[3]) v->storage;
184 v->count = 0;
185 v->flags = flags | VEC_MALLOC ;
186 }
187
188 void _mesa_vector1f_alloc( GLvector1f *v, GLuint flags, GLuint count,
189 GLuint alignment )
190 {
191 v->stride = sizeof(GLfloat);
192 v->storage = v->start = (GLfloat *)
193 ALIGN_MALLOC( count * sizeof(GLfloat), alignment );
194 v->data = v->start;
195 v->count = 0;
196 v->flags = flags | VEC_MALLOC ;
197 }
198
199 void _mesa_vector4ub_alloc( GLvector4ub *v, GLuint flags, GLuint count,
200 GLuint alignment )
201 {
202 v->stride = 4 * sizeof(GLubyte);
203 v->storage = ALIGN_MALLOC( count * 4 * sizeof(GLubyte), alignment );
204 v->start = (GLubyte *) v->storage;
205 v->data = (GLubyte (*)[4]) v->storage;
206 v->count = 0;
207 v->flags = flags | VEC_MALLOC ;
208 }
209
210 void _mesa_vector4chan_alloc( GLvector4chan *v, GLuint flags, GLuint count,
211 GLuint alignment )
212 {
213 v->stride = 4 * sizeof(GLchan);
214 v->storage = ALIGN_MALLOC( count * 4 * sizeof(GLchan), alignment );
215 v->start = (GLchan *) v->storage;
216 v->data = (GLchan (*)[4]) v->storage;
217 v->count = 0;
218 v->flags = flags | VEC_MALLOC ;
219 }
220
221 void _mesa_vector4us_alloc( GLvector4us *v, GLuint flags, GLuint count,
222 GLuint alignment )
223 {
224 v->stride = 4 * sizeof(GLushort);
225 v->storage = ALIGN_MALLOC( count * 4 * sizeof(GLushort), alignment );
226 v->start = (GLushort *) v->storage;
227 v->data = (GLushort (*)[4]) v->storage;
228 v->count = 0;
229 v->flags = flags | VEC_MALLOC ;
230 }
231
232 void _mesa_vector1ub_alloc( GLvector1ub *v, GLuint flags, GLuint count,
233 GLuint alignment )
234 {
235 v->stride = 1 * sizeof(GLubyte);
236 v->storage = ALIGN_MALLOC( count * sizeof(GLubyte), alignment );
237 v->start = (GLubyte *) v->storage;
238 v->data = (GLubyte *) v->storage;
239 v->count = 0;
240 v->flags = flags | VEC_MALLOC ;
241 }
242
243 void _mesa_vector1ui_alloc( GLvector1ui *v, GLuint flags, GLuint count,
244 GLuint alignment )
245 {
246 v->stride = 1 * sizeof(GLuint);
247 v->storage = ALIGN_MALLOC( count * sizeof(GLuint), alignment );
248 v->start = (GLuint *) v->storage;
249 v->data = (GLuint *) v->storage;
250 v->count = 0;
251 v->flags = flags | VEC_MALLOC ;
252 }
253
254
255
256 /*
257 * Vector deallocation. Free whatever memory is pointed to by the
258 * vector's storage field if the VEC_MALLOC flag is set.
259 * DO NOT free the GLvector object itself, though.
260 */
261
262
263 void _mesa_vector4f_free( GLvector4f *v )
264 {
265 if (v->flags & VEC_MALLOC) {
266 ALIGN_FREE( v->storage );
267 v->data = NULL;
268 v->start = NULL;
269 v->storage = NULL;
270 v->flags &= ~VEC_MALLOC;
271 }
272 }
273
274 void _mesa_vector3f_free( GLvector3f *v )
275 {
276 if (v->flags & VEC_MALLOC) {
277 ALIGN_FREE( v->storage );
278 v->data = 0;
279 v->start = 0;
280 v->storage = 0;
281 v->flags &= ~VEC_MALLOC;
282 }
283 }
284
285 void _mesa_vector1f_free( GLvector1f *v )
286 {
287 if (v->flags & VEC_MALLOC) {
288 ALIGN_FREE( v->storage );
289 v->data = NULL;
290 v->start = NULL;
291 v->storage = NULL;
292 v->flags &= ~VEC_MALLOC;
293 }
294 }
295
296 void _mesa_vector4ub_free( GLvector4ub *v )
297 {
298 if (v->flags & VEC_MALLOC) {
299 ALIGN_FREE( v->storage );
300 v->data = NULL;
301 v->start = NULL;
302 v->storage = NULL;
303 v->flags &= ~VEC_MALLOC;
304 }
305 }
306
307 void _mesa_vector4chan_free( GLvector4chan *v )
308 {
309 if (v->flags & VEC_MALLOC) {
310 ALIGN_FREE( v->storage );
311 v->data = NULL;
312 v->start = NULL;
313 v->storage = NULL;
314 v->flags &= ~VEC_MALLOC;
315 }
316 }
317
318 void _mesa_vector4us_free( GLvector4us *v )
319 {
320 if (v->flags & VEC_MALLOC) {
321 ALIGN_FREE( v->storage );
322 v->data = NULL;
323 v->start = NULL;
324 v->storage = NULL;
325 v->flags &= ~VEC_MALLOC;
326 }
327 }
328
329 void _mesa_vector1ub_free( GLvector1ub *v )
330 {
331 if (v->flags & VEC_MALLOC) {
332 ALIGN_FREE( v->storage );
333 v->data = NULL;
334 v->start = NULL;
335 v->storage = NULL;
336 v->flags &= ~VEC_MALLOC;
337 }
338 }
339
340 void _mesa_vector1ui_free( GLvector1ui *v )
341 {
342 if (v->flags & VEC_MALLOC) {
343 ALIGN_FREE( v->storage );
344 v->data = NULL;
345 v->start = NULL;
346 v->storage = NULL;
347 v->flags &= ~VEC_MALLOC;
348 }
349 }
350
351
352 /*
353 * For debugging
354 */
355 void _mesa_vector4f_print( GLvector4f *v, GLubyte *cullmask, GLboolean culling )
356 {
357 GLfloat c[4] = { 0, 0, 0, 1 };
358 const char *templates[5] = {
359 "%d:\t0, 0, 0, 1\n",
360 "%d:\t%f, 0, 0, 1\n",
361 "%d:\t%f, %f, 0, 1\n",
362 "%d:\t%f, %f, %f, 1\n",
363 "%d:\t%f, %f, %f, %f\n"
364 };
365
366 const char *t = templates[v->size];
367 GLfloat *d = (GLfloat *)v->data;
368 GLuint j, i = 0, count;
369
370 _mesa_printf("data-start\n");
371 for ( ; d != v->start ; STRIDE_F(d, v->stride), i++)
372 _mesa_printf(t, i, d[0], d[1], d[2], d[3]);
373
374 _mesa_printf("start-count(%u)\n", v->count);
375 count = i + v->count;
376
377 if (culling) {
378 for ( ; i < count ; STRIDE_F(d, v->stride), i++)
379 if (cullmask[i])
380 _mesa_printf(t, i, d[0], d[1], d[2], d[3]);
381 }
382 else {
383 for ( ; i < count ; STRIDE_F(d, v->stride), i++)
384 _mesa_printf(t, i, d[0], d[1], d[2], d[3]);
385 }
386
387 for (j = v->size ; j < 4; j++) {
388 if ((v->flags & (1<<j)) == 0) {
389
390 _mesa_printf("checking col %u is clean as advertised ", j);
391
392 for (i = 0, d = (GLfloat *) v->data ;
393 i < count && d[j] == c[j] ;
394 i++, STRIDE_F(d, v->stride)) {};
395
396 if (i == count)
397 _mesa_printf(" --> ok\n");
398 else
399 _mesa_printf(" --> Failed at %u ******\n", i);
400 }
401 }
402 }
403
404
405 /*
406 * For debugging
407 */
408 void _mesa_vector3f_print( GLvector3f *v, GLubyte *cullmask, GLboolean culling )
409 {
410 GLfloat *d = (GLfloat *)v->data;
411 GLuint i = 0, count;
412
413 _mesa_printf("data-start\n");
414 for ( ; d != v->start ; STRIDE_F(d,v->stride), i++)
415 _mesa_printf( "%u:\t%f, %f, %f\n", i, d[0], d[1], d[2]);
416
417 _mesa_printf("start-count(%u)\n", v->count);
418 count = i + v->count;
419
420 if (culling) {
421 for ( ; i < count ; STRIDE_F(d,v->stride), i++)
422 if (cullmask[i])
423 _mesa_printf("%u:\t%f, %f, %f\n", i, d[0], d[1], d[2]);
424 }
425 else {
426 for ( ; i < count ; STRIDE_F(d,v->stride), i++)
427 _mesa_printf("%u:\t%f, %f, %f\n", i, d[0], d[1], d[2]);
428 }
429 }