blob: 1e0616324eb465bdfd5cf5a56ae05d5da5de4e62 [file] [log] [blame]
Keith Whitwellfabb9732003-12-21 17:54:31 +00001/*
2 * Copyright 2003 Tungsten Graphics, inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Keith Whitwell <keithw@tungstengraphics.com>
26 */
27
Keith Whitwell79073402004-01-05 09:43:42 +000028#include "glheader.h"
29#include "context.h"
30#include "colormac.h"
31
32#include "t_context.h"
33#include "t_vertex.h"
34
35
36/* Build and manage clipspace/ndc/window vertices.
37 *
38 * Another new mechanism designed and crying out for codegen. Before
39 * that, it would be very interesting to investigate the merger of
40 * these vertices and those built in t_vtx_*.
41 */
Keith Whitwellfabb9732003-12-21 17:54:31 +000042
43
44
Keith Whitwell203dca42004-01-06 20:13:41 +000045
Keith Whitwell79073402004-01-05 09:43:42 +000046#define GET_VERTEX_STATE(ctx) &(TNL_CONTEXT(ctx)->clipspace)
Keith Whitwellfabb9732003-12-21 17:54:31 +000047
Keith Whitwell58822572004-01-05 15:24:53 +000048static void insert_4f_viewport_4( const struct tnl_clipspace_attr *a, GLubyte *v,
Keith Whitwellfabb9732003-12-21 17:54:31 +000049 const GLfloat *in )
50{
51 GLfloat *out = (GLfloat *)v;
52 const GLfloat * const vp = a->vp;
53
54 out[0] = vp[0] * in[0] + vp[12];
55 out[1] = vp[5] * in[1] + vp[13];
56 out[2] = vp[10] * in[2] + vp[14];
57 out[3] = in[3];
58}
59
Keith Whitwell58822572004-01-05 15:24:53 +000060static void insert_4f_viewport_3( const struct tnl_clipspace_attr *a, GLubyte *v,
61 const GLfloat *in )
62{
63 GLfloat *out = (GLfloat *)v;
64 const GLfloat * const vp = a->vp;
65
66 out[0] = vp[0] * in[0] + vp[12];
67 out[1] = vp[5] * in[1] + vp[13];
68 out[2] = vp[10] * in[2] + vp[14];
69 out[3] = 1;
70}
71
72static void insert_4f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
73 const GLfloat *in )
74{
75 GLfloat *out = (GLfloat *)v;
76 const GLfloat * const vp = a->vp;
77
78 out[0] = vp[0] * in[0] + vp[12];
79 out[1] = vp[5] * in[1] + vp[13];
80 out[2] = vp[14];
81 out[3] = 1;
82}
83
84static void insert_4f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
85 const GLfloat *in )
86{
87 GLfloat *out = (GLfloat *)v;
88 const GLfloat * const vp = a->vp;
89
90 out[0] = vp[0] * in[0] + vp[12];
91 out[1] = vp[13];
92 out[2] = vp[14];
93 out[3] = 1;
94}
95
96static void insert_3f_viewport_3( const struct tnl_clipspace_attr *a, GLubyte *v,
Keith Whitwellfabb9732003-12-21 17:54:31 +000097 const GLfloat *in )
98{
99 GLfloat *out = (GLfloat *)v;
100 const GLfloat * const vp = a->vp;
101
102 out[0] = vp[0] * in[0] + vp[12];
103 out[1] = vp[5] * in[1] + vp[13];
104 out[2] = vp[10] * in[2] + vp[14];
105}
106
Keith Whitwell58822572004-01-05 15:24:53 +0000107static void insert_3f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
108 const GLfloat *in )
109{
110 GLfloat *out = (GLfloat *)v;
111 const GLfloat * const vp = a->vp;
112
113 out[0] = vp[0] * in[0] + vp[12];
114 out[1] = vp[5] * in[1] + vp[13];
115 out[2] = vp[10] * in[2] + vp[14];
116}
117
118static void insert_3f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
119 const GLfloat *in )
120{
121 GLfloat *out = (GLfloat *)v;
122 const GLfloat * const vp = a->vp;
123
124 out[0] = vp[0] * in[0] + vp[12];
125 out[1] = vp[13];
126 out[2] = vp[14];
127}
128
129static void insert_2f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
Keith Whitwellfabb9732003-12-21 17:54:31 +0000130 const GLfloat *in )
131{
132 GLfloat *out = (GLfloat *)v;
133 const GLfloat * const vp = a->vp;
134
135 out[0] = vp[0] * in[0] + vp[12];
136 out[1] = vp[5] * in[1] + vp[13];
137}
138
Keith Whitwell58822572004-01-05 15:24:53 +0000139static void insert_2f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
140 const GLfloat *in )
141{
142 GLfloat *out = (GLfloat *)v;
143 const GLfloat * const vp = a->vp;
144
145 out[0] = vp[0] * in[0] + vp[12];
146 out[1] = vp[13];
147}
Keith Whitwellfabb9732003-12-21 17:54:31 +0000148
Keith Whitwell58822572004-01-05 15:24:53 +0000149
150static void insert_4f_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000151{
152 GLfloat *out = (GLfloat *)(v);
153
154 out[0] = in[0];
155 out[1] = in[1];
156 out[2] = in[2];
157 out[3] = in[3];
158}
159
Keith Whitwell58822572004-01-05 15:24:53 +0000160static void insert_4f_3( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
Keith Whitwell79073402004-01-05 09:43:42 +0000161{
162 GLfloat *out = (GLfloat *)(v);
163
164 out[0] = in[0];
165 out[1] = in[1];
166 out[2] = in[2];
167 out[3] = 1;
168}
169
Keith Whitwell58822572004-01-05 15:24:53 +0000170static void insert_4f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
Keith Whitwell79073402004-01-05 09:43:42 +0000171{
172 GLfloat *out = (GLfloat *)(v);
173
174 out[0] = in[0];
175 out[1] = in[1];
176 out[2] = 0;
177 out[3] = 1;
178}
179
Keith Whitwell58822572004-01-05 15:24:53 +0000180static void insert_4f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
Keith Whitwell79073402004-01-05 09:43:42 +0000181{
182 GLfloat *out = (GLfloat *)(v);
183
184 out[0] = in[0];
185 out[1] = 0;
186 out[2] = 0;
187 out[3] = 1;
188}
189
Keith Whitwell58822572004-01-05 15:24:53 +0000190static void insert_3f_xyw_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
191{
192 GLfloat *out = (GLfloat *)(v);
193
194 out[0] = in[0];
195 out[1] = in[1];
196 out[2] = in[3];
197}
198
199static void insert_3f_xyw_err( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
200{
201 abort();
202}
203
204static void insert_3f_3( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
205{
206 GLfloat *out = (GLfloat *)(v);
207
208 out[0] = in[0];
209 out[1] = in[1];
210 out[2] = in[2];
211}
212
213static void insert_3f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
214{
215 GLfloat *out = (GLfloat *)(v);
216
217 out[0] = in[0];
218 out[1] = in[1];
219 out[2] = 0;
220}
221
222static void insert_3f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
223{
224 GLfloat *out = (GLfloat *)(v);
225
226 out[0] = in[0];
227 out[1] = 0;
228 out[2] = 0;
229}
230
231
232static void insert_2f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
233{
234 GLfloat *out = (GLfloat *)(v);
235
236 out[0] = in[0];
237 out[1] = in[1];
238}
239
240static void insert_2f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
241{
242 GLfloat *out = (GLfloat *)(v);
243
244 out[0] = in[0];
245 out[1] = 0;
246}
247
248static void insert_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
249{
250 GLfloat *out = (GLfloat *)(v);
251
252 out[0] = in[0];
253}
254
255static void insert_4chan_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v,
Keith Whitwell79073402004-01-05 09:43:42 +0000256 const GLfloat *in )
257{
258 GLchan *c = (GLchan *)v;
259 UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
260 UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]);
261 UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]);
262 UNCLAMPED_FLOAT_TO_CHAN(c[3], in[3]);
263}
264
Keith Whitwell58822572004-01-05 15:24:53 +0000265static void insert_4chan_4f_rgba_3( const struct tnl_clipspace_attr *a, GLubyte *v,
266 const GLfloat *in )
267{
268 GLchan *c = (GLchan *)v;
269 UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
270 UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]);
271 UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]);
272 c[3] = CHAN_MAX;
273}
274
275static void insert_4chan_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v,
276 const GLfloat *in )
277{
278 GLchan *c = (GLchan *)v;
279 UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
280 UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]);
281 c[2] = 0;
282 c[3] = CHAN_MAX;
283}
284
285static void insert_4chan_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v,
286 const GLfloat *in )
287{
288 GLchan *c = (GLchan *)v;
289 UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
290 c[1] = 0;
291 c[2] = 0;
292 c[3] = CHAN_MAX;
293}
294
295static void insert_4ub_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v,
Keith Whitwellfabb9732003-12-21 17:54:31 +0000296 const GLfloat *in )
297{
298 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
299 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
300 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
301 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
302}
303
Keith Whitwell58822572004-01-05 15:24:53 +0000304static void insert_4ub_4f_rgba_3( const struct tnl_clipspace_attr *a, GLubyte *v,
305 const GLfloat *in )
306{
307 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
308 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
309 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
310 v[3] = 0xff;
311}
312
313static void insert_4ub_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v,
314 const GLfloat *in )
315{
316 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
317 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
318 v[2] = 0;
319 v[3] = 0xff;
320}
321
322static void insert_4ub_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v,
323 const GLfloat *in )
324{
325 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
326 v[1] = 0;
327 v[2] = 0;
328 v[3] = 0xff;
329}
330
331static void insert_4ub_4f_bgra_4( const struct tnl_clipspace_attr *a, GLubyte *v,
Keith Whitwellfabb9732003-12-21 17:54:31 +0000332 const GLfloat *in )
333{
334 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
335 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
336 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
337 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
338}
339
Keith Whitwell58822572004-01-05 15:24:53 +0000340static void insert_4ub_4f_bgra_3( const struct tnl_clipspace_attr *a, GLubyte *v,
341 const GLfloat *in )
342{
343 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
344 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
345 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
346 v[3] = 0xff;
347}
348
349static void insert_4ub_4f_bgra_2( const struct tnl_clipspace_attr *a, GLubyte *v,
350 const GLfloat *in )
351{
352 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
353 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
354 v[0] = 0;
355 v[3] = 0xff;
356}
357
358static void insert_4ub_4f_bgra_1( const struct tnl_clipspace_attr *a, GLubyte *v,
359 const GLfloat *in )
360{
361 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
362 v[1] = 0;
363 v[0] = 0;
364 v[3] = 0xff;
365}
366
367static void insert_3ub_3f_rgb_3( const struct tnl_clipspace_attr *a, GLubyte *v,
Keith Whitwellfabb9732003-12-21 17:54:31 +0000368 const GLfloat *in )
369{
370 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
371 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
372 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
373}
374
Keith Whitwell58822572004-01-05 15:24:53 +0000375static void insert_3ub_3f_rgb_2( const struct tnl_clipspace_attr *a, GLubyte *v,
Keith Whitwellfabb9732003-12-21 17:54:31 +0000376 const GLfloat *in )
377{
Keith Whitwell58822572004-01-05 15:24:53 +0000378 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
379 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
380 v[2] = 0;
381}
382
383static void insert_3ub_3f_rgb_1( const struct tnl_clipspace_attr *a, GLubyte *v,
384 const GLfloat *in )
385{
386 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
387 v[1] = 0;
388 v[2] = 0;
389}
390
391static void insert_3ub_3f_bgr_3( const struct tnl_clipspace_attr *a, GLubyte *v,
392 const GLfloat *in )
393{
Keith Whitwellfabb9732003-12-21 17:54:31 +0000394 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
395 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
396 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
397}
398
Keith Whitwell58822572004-01-05 15:24:53 +0000399static void insert_3ub_3f_bgr_2( const struct tnl_clipspace_attr *a, GLubyte *v,
400 const GLfloat *in )
401{
402 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
403 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
404 v[0] = 0;
405}
406
407static void insert_3ub_3f_bgr_1( const struct tnl_clipspace_attr *a, GLubyte *v,
408 const GLfloat *in )
409{
410 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
411 v[1] = 0;
412 v[0]= 0;
413}
414
415
416static void insert_1ub_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v,
Keith Whitwellfabb9732003-12-21 17:54:31 +0000417 const GLfloat *in )
418{
419 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
420}
421
422
423/***********************************************************************
424 * Functions to perform the reverse operations to the above, for
425 * swrast translation and clip-interpolation.
426 *
427 * Currently always extracts a full 4 floats.
428 */
429
Keith Whitwell79073402004-01-05 09:43:42 +0000430static void extract_4f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out,
Keith Whitwell58822572004-01-05 15:24:53 +0000431 const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000432{
433 const GLfloat *in = (const GLfloat *)v;
434 const GLfloat * const vp = a->vp;
435
436 out[0] = (in[0] - vp[12]) / vp[0];
437 out[1] = (in[1] - vp[13]) / vp[5];
438 out[2] = (in[2] - vp[14]) / vp[10];
439 out[3] = in[3];
440}
441
Keith Whitwell79073402004-01-05 09:43:42 +0000442static void extract_3f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out,
Keith Whitwell58822572004-01-05 15:24:53 +0000443 const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000444{
445 const GLfloat *in = (const GLfloat *)v;
446 const GLfloat * const vp = a->vp;
447
448 out[0] = (in[0] - vp[12]) / vp[0];
449 out[1] = (in[1] - vp[13]) / vp[5];
450 out[2] = (in[2] - vp[14]) / vp[10];
451 out[3] = 1;
452}
453
454
Keith Whitwell79073402004-01-05 09:43:42 +0000455static void extract_2f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out,
Keith Whitwell58822572004-01-05 15:24:53 +0000456 const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000457{
458 const GLfloat *in = (const GLfloat *)v;
459 const GLfloat * const vp = a->vp;
460
461 out[0] = (in[0] - vp[12]) / vp[0];
462 out[1] = (in[1] - vp[13]) / vp[5];
463 out[2] = 0;
464 out[3] = 1;
465}
466
467
Keith Whitwell58822572004-01-05 15:24:53 +0000468static void extract_4f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000469{
470 const GLfloat *in = (const GLfloat *)v;
471
472 out[0] = in[0];
473 out[1] = in[1];
474 out[2] = in[2];
475 out[3] = in[3];
476}
477
Keith Whitwell58822572004-01-05 15:24:53 +0000478static void extract_3f_xyw( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000479{
480 const GLfloat *in = (const GLfloat *)v;
481
482 out[0] = in[0];
483 out[1] = in[1];
484 out[2] = in[3];
485 out[3] = 1;
486}
487
488
Keith Whitwell58822572004-01-05 15:24:53 +0000489static void extract_3f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000490{
491 const GLfloat *in = (const GLfloat *)v;
492
493 out[0] = in[0];
494 out[1] = in[1];
495 out[2] = in[2];
496 out[3] = 1;
497}
498
499
Keith Whitwell58822572004-01-05 15:24:53 +0000500static void extract_2f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000501{
502 const GLfloat *in = (const GLfloat *)v;
503
504 out[0] = in[0];
505 out[1] = in[1];
506 out[2] = 0;
507 out[3] = 1;
508}
509
Keith Whitwell58822572004-01-05 15:24:53 +0000510static void extract_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000511{
512 const GLfloat *in = (const GLfloat *)v;
513
514 out[0] = in[0];
515 out[1] = 0;
516 out[2] = 0;
517 out[3] = 1;
518}
519
Keith Whitwell79073402004-01-05 09:43:42 +0000520static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out,
Keith Whitwell58822572004-01-05 15:24:53 +0000521 const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000522{
Keith Whitwell79073402004-01-05 09:43:42 +0000523 GLchan *c = (GLchan *)v;
524
525 out[0] = CHAN_TO_FLOAT(c[0]);
526 out[1] = CHAN_TO_FLOAT(c[1]);
527 out[2] = CHAN_TO_FLOAT(c[2]);
528 out[3] = CHAN_TO_FLOAT(c[3]);
Keith Whitwellfabb9732003-12-21 17:54:31 +0000529}
530
Keith Whitwell79073402004-01-05 09:43:42 +0000531static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out,
Keith Whitwell58822572004-01-05 15:24:53 +0000532 const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000533{
Keith Whitwell79073402004-01-05 09:43:42 +0000534 out[0] = UBYTE_TO_FLOAT(v[0]);
535 out[1] = UBYTE_TO_FLOAT(v[1]);
536 out[2] = UBYTE_TO_FLOAT(v[2]);
537 out[3] = UBYTE_TO_FLOAT(v[3]);
Keith Whitwellfabb9732003-12-21 17:54:31 +0000538}
539
Keith Whitwell79073402004-01-05 09:43:42 +0000540static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr *a, GLfloat *out,
Keith Whitwell58822572004-01-05 15:24:53 +0000541 const GLubyte *v )
Keith Whitwell79073402004-01-05 09:43:42 +0000542{
543 out[2] = UBYTE_TO_FLOAT(v[0]);
544 out[1] = UBYTE_TO_FLOAT(v[1]);
545 out[0] = UBYTE_TO_FLOAT(v[2]);
546 out[3] = UBYTE_TO_FLOAT(v[3]);
547}
548
549static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr *a, GLfloat *out,
Keith Whitwell58822572004-01-05 15:24:53 +0000550 const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000551{
Keith Whitwell79073402004-01-05 09:43:42 +0000552 out[0] = UBYTE_TO_FLOAT(v[0]);
553 out[1] = UBYTE_TO_FLOAT(v[1]);
554 out[2] = UBYTE_TO_FLOAT(v[2]);
Keith Whitwellfabb9732003-12-21 17:54:31 +0000555 out[3] = 1;
556}
557
Keith Whitwell79073402004-01-05 09:43:42 +0000558static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr *a, GLfloat *out,
Keith Whitwell58822572004-01-05 15:24:53 +0000559 const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000560{
Keith Whitwell79073402004-01-05 09:43:42 +0000561 out[2] = UBYTE_TO_FLOAT(v[0]);
562 out[1] = UBYTE_TO_FLOAT(v[1]);
563 out[0] = UBYTE_TO_FLOAT(v[2]);
Keith Whitwellfabb9732003-12-21 17:54:31 +0000564 out[3] = 1;
565}
566
Keith Whitwell58822572004-01-05 15:24:53 +0000567static void extract_1ub_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000568{
Keith Whitwell79073402004-01-05 09:43:42 +0000569 out[0] = UBYTE_TO_FLOAT(v[0]);
Keith Whitwellfabb9732003-12-21 17:54:31 +0000570 out[1] = 0;
571 out[2] = 0;
572 out[3] = 1;
573}
574
Keith Whitwell79073402004-01-05 09:43:42 +0000575
Keith Whitwell79073402004-01-05 09:43:42 +0000576struct {
Keith Whitwell58822572004-01-05 15:24:53 +0000577 const char *name;
Keith Whitwell79073402004-01-05 09:43:42 +0000578 extract_func extract;
Keith Whitwell58822572004-01-05 15:24:53 +0000579 insert_func insert[4];
Keith Whitwell79073402004-01-05 09:43:42 +0000580 GLuint attrsize;
581} format_info[EMIT_MAX] = {
582
Keith Whitwell58822572004-01-05 15:24:53 +0000583 { "1f",
584 extract_1f,
585 { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 },
Keith Whitwell79073402004-01-05 09:43:42 +0000586 sizeof(GLfloat) },
587
Keith Whitwell58822572004-01-05 15:24:53 +0000588 { "2f",
589 extract_2f,
590 { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 },
Keith Whitwell79073402004-01-05 09:43:42 +0000591 2 * sizeof(GLfloat) },
592
Keith Whitwell58822572004-01-05 15:24:53 +0000593 { "3f",
594 extract_3f,
595 { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 },
Keith Whitwell79073402004-01-05 09:43:42 +0000596 3 * sizeof(GLfloat) },
597
Keith Whitwell58822572004-01-05 15:24:53 +0000598 { "4f",
599 extract_4f,
600 { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 },
Keith Whitwell79073402004-01-05 09:43:42 +0000601 4 * sizeof(GLfloat) },
602
Keith Whitwell58822572004-01-05 15:24:53 +0000603 { "2f_viewport",
604 extract_2f_viewport,
605 { insert_2f_viewport_1, insert_2f_viewport_2, insert_2f_viewport_2,
606 insert_2f_viewport_2 },
Keith Whitwell79073402004-01-05 09:43:42 +0000607 2 * sizeof(GLfloat) },
608
Keith Whitwell58822572004-01-05 15:24:53 +0000609 { "3f_viewport",
610 extract_3f_viewport,
611 { insert_3f_viewport_1, insert_3f_viewport_2, insert_3f_viewport_3,
612 insert_3f_viewport_3 },
Keith Whitwell79073402004-01-05 09:43:42 +0000613 3 * sizeof(GLfloat) },
614
Keith Whitwell58822572004-01-05 15:24:53 +0000615 { "4f_viewport",
616 extract_4f_viewport,
617 { insert_4f_viewport_1, insert_4f_viewport_2, insert_4f_viewport_3,
618 insert_4f_viewport_4 },
Keith Whitwell79073402004-01-05 09:43:42 +0000619 4 * sizeof(GLfloat) },
620
Keith Whitwell58822572004-01-05 15:24:53 +0000621 { "3f_xyw",
622 extract_3f_xyw,
623 { insert_3f_xyw_err, insert_3f_xyw_err, insert_3f_xyw_err,
624 insert_3f_xyw_4 },
Keith Whitwell79073402004-01-05 09:43:42 +0000625 3 * sizeof(GLfloat) },
626
Keith Whitwell58822572004-01-05 15:24:53 +0000627 { "1ub_1f",
628 extract_1ub_1f,
629 { insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1 },
Keith Whitwell79073402004-01-05 09:43:42 +0000630 sizeof(GLubyte) },
631
Keith Whitwell58822572004-01-05 15:24:53 +0000632 { "3ub_3f_rgb",
633 extract_3ub_3f_rgb,
634 { insert_3ub_3f_rgb_1, insert_3ub_3f_rgb_2, insert_3ub_3f_rgb_3,
635 insert_3ub_3f_rgb_3 },
Keith Whitwell79073402004-01-05 09:43:42 +0000636 3 * sizeof(GLubyte) },
637
Keith Whitwell58822572004-01-05 15:24:53 +0000638 { "3ub_3f_bgr",
639 extract_3ub_3f_bgr,
640 { insert_3ub_3f_bgr_1, insert_3ub_3f_bgr_2, insert_3ub_3f_bgr_3,
641 insert_3ub_3f_bgr_3 },
Keith Whitwell79073402004-01-05 09:43:42 +0000642 3 * sizeof(GLubyte) },
643
Keith Whitwell58822572004-01-05 15:24:53 +0000644 { "4ub_4f_rgba",
645 extract_4ub_4f_rgba,
646 { insert_4ub_4f_rgba_1, insert_4ub_4f_rgba_2, insert_4ub_4f_rgba_3,
647 insert_4ub_4f_rgba_4 },
Keith Whitwell79073402004-01-05 09:43:42 +0000648 4 * sizeof(GLubyte) },
649
Keith Whitwell58822572004-01-05 15:24:53 +0000650 { "4ub_4f_bgra",
651 extract_4ub_4f_bgra,
652 { insert_4ub_4f_bgra_1, insert_4ub_4f_bgra_2, insert_4ub_4f_bgra_3,
653 insert_4ub_4f_bgra_4 },
Keith Whitwell79073402004-01-05 09:43:42 +0000654 4 * sizeof(GLubyte) },
655
Keith Whitwell58822572004-01-05 15:24:53 +0000656 { "4chan_4f_rgba",
657 extract_4chan_4f_rgba,
658 { insert_4chan_4f_rgba_1, insert_4chan_4f_rgba_2, insert_4chan_4f_rgba_3,
659 insert_4chan_4f_rgba_4 },
660 4 * sizeof(GLchan) }
Keith Whitwell79073402004-01-05 09:43:42 +0000661
662};
663
664
Keith Whitwellfabb9732003-12-21 17:54:31 +0000665/***********************************************************************
666 * Generic (non-codegen) functions for whole vertices or groups of
667 * vertices
668 */
669
670static void generic_emit( GLcontext *ctx,
671 GLuint start, GLuint end,
Keith Whitwell79073402004-01-05 09:43:42 +0000672 void *dest )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000673{
Keith Whitwell79073402004-01-05 09:43:42 +0000674 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
675 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
676 struct tnl_clipspace_attr *a = vtx->attr;
Keith Whitwell58822572004-01-05 15:24:53 +0000677 GLubyte *v = (GLubyte *)dest;
Karl Schultzc6c4cd82004-01-13 01:11:09 +0000678 GLuint i, j;
Keith Whitwell79073402004-01-05 09:43:42 +0000679 GLuint count = vtx->attr_count;
680 GLuint stride;
Keith Whitwellfabb9732003-12-21 17:54:31 +0000681
Keith Whitwell79073402004-01-05 09:43:42 +0000682 for (j = 0; j < count; j++) {
683 GLvector4f *vptr = VB->AttribPtr[a[j].attrib];
684 a[j].inputstride = vptr->stride;
Keith Whitwell44d4a8f2004-01-06 00:18:03 +0000685 a[j].inputptr = ((GLubyte *)vptr->data) + start * vptr->stride;
Keith Whitwell58822572004-01-05 15:24:53 +0000686 a[j].emit = a[j].insert[vptr->size - 1];
Keith Whitwellfabb9732003-12-21 17:54:31 +0000687 }
688
Keith Whitwell79073402004-01-05 09:43:42 +0000689 end -= start;
690 stride = vtx->vertex_size;
691
Keith Whitwellfabb9732003-12-21 17:54:31 +0000692 for (i = 0 ; i < end ; i++, v += stride) {
Keith Whitwell79073402004-01-05 09:43:42 +0000693 for (j = 0; j < count; j++) {
Keith Whitwell58822572004-01-05 15:24:53 +0000694 GLfloat *in = (GLfloat *)a[j].inputptr;
695 a[j].inputptr += a[j].inputstride;
696 a[j].emit( &a[j], v + a[j].vertoffset, in );
Keith Whitwellfabb9732003-12-21 17:54:31 +0000697 }
698 }
699}
700
701
702static void generic_interp( GLcontext *ctx,
703 GLfloat t,
704 GLuint edst, GLuint eout, GLuint ein,
705 GLboolean force_boundary )
706{
Keith Whitwell79073402004-01-05 09:43:42 +0000707 TNLcontext *tnl = TNL_CONTEXT(ctx);
708 struct vertex_buffer *VB = &tnl->vb;
709 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
Keith Whitwell58822572004-01-05 15:24:53 +0000710 GLubyte *vin = vtx->vertex_buf + ein * vtx->vertex_size;
711 GLubyte *vout = vtx->vertex_buf + eout * vtx->vertex_size;
712 GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size;
Keith Whitwell79073402004-01-05 09:43:42 +0000713 const struct tnl_clipspace_attr *a = vtx->attr;
Keith Whitwellfabb9732003-12-21 17:54:31 +0000714 int attr_count = vtx->attr_count;
715 int j;
Keith Whitwell79073402004-01-05 09:43:42 +0000716
717 if (tnl->NeedNdcCoords) {
718 const GLfloat *dstclip = VB->ClipPtr->data[edst];
Keith Whitwellfb2a95b2004-01-08 13:55:24 +0000719 if (dstclip[3] != 0.0) {
Karl Schultzc6c4cd82004-01-13 01:11:09 +0000720 const GLfloat w = 1.0f / dstclip[3];
Keith Whitwellfb2a95b2004-01-08 13:55:24 +0000721 GLfloat pos[4];
Keith Whitwell79073402004-01-05 09:43:42 +0000722
Keith Whitwellfb2a95b2004-01-08 13:55:24 +0000723 pos[0] = dstclip[0] * w;
724 pos[1] = dstclip[1] * w;
725 pos[2] = dstclip[2] * w;
726 pos[3] = w;
Keith Whitwell79073402004-01-05 09:43:42 +0000727
Keith Whitwellfb2a95b2004-01-08 13:55:24 +0000728 a[0].insert[4-1]( &a[0], vdst, pos );
729 }
Keith Whitwell79073402004-01-05 09:43:42 +0000730 }
731 else {
Keith Whitwell58822572004-01-05 15:24:53 +0000732 a[0].insert[4-1]( &a[0], vdst, VB->ClipPtr->data[edst] );
Keith Whitwell79073402004-01-05 09:43:42 +0000733 }
734
735
736 for (j = 1; j < attr_count; j++) {
Keith Whitwellfabb9732003-12-21 17:54:31 +0000737 GLfloat fin[4], fout[4], fdst[4];
Keith Whitwell79073402004-01-05 09:43:42 +0000738
739 a[j].extract( &a[j], fin, vin + a[j].vertoffset );
740 a[j].extract( &a[j], fout, vout + a[j].vertoffset );
Keith Whitwellfabb9732003-12-21 17:54:31 +0000741
742 INTERP_F( t, fdst[3], fout[3], fin[3] );
743 INTERP_F( t, fdst[2], fout[2], fin[2] );
744 INTERP_F( t, fdst[1], fout[1], fin[1] );
745 INTERP_F( t, fdst[0], fout[0], fin[0] );
746
Keith Whitwell58822572004-01-05 15:24:53 +0000747 a[j].insert[4-1]( &a[j], vdst + a[j].vertoffset, fdst );
Keith Whitwellfabb9732003-12-21 17:54:31 +0000748 }
749}
750
751
752/* Extract color attributes from one vertex and insert them into
753 * another. (Shortcircuit extract/insert with memcpy).
754 */
Keith Whitwell79073402004-01-05 09:43:42 +0000755static void generic_copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000756{
Keith Whitwell79073402004-01-05 09:43:42 +0000757 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
Keith Whitwell58822572004-01-05 15:24:53 +0000758 GLubyte *vsrc = vtx->vertex_buf + esrc * vtx->vertex_size;
759 GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size;
Keith Whitwell79073402004-01-05 09:43:42 +0000760 const struct tnl_clipspace_attr *a = vtx->attr;
Keith Whitwellfabb9732003-12-21 17:54:31 +0000761 int attr_count = vtx->attr_count;
762 int j;
763
764 for (j = 0; j < attr_count; j++) {
Keith Whitwell79073402004-01-05 09:43:42 +0000765 if (a[j].attrib == VERT_ATTRIB_COLOR0 ||
766 a[j].attrib == VERT_ATTRIB_COLOR1) {
Keith Whitwellfabb9732003-12-21 17:54:31 +0000767
Brian Paul3663c0f2004-01-15 00:29:51 +0000768 _mesa_memcpy( vdst + a[j].vertoffset,
769 vsrc + a[j].vertoffset,
770 a[j].vertattrsize );
Keith Whitwell79073402004-01-05 09:43:42 +0000771 }
Keith Whitwellfabb9732003-12-21 17:54:31 +0000772 }
773}
774
Keith Whitwellfabb9732003-12-21 17:54:31 +0000775
Keith Whitwell79073402004-01-05 09:43:42 +0000776/* Helper functions for hardware which doesn't put back colors and/or
777 * edgeflags into vertices.
778 */
779static void generic_interp_extras( GLcontext *ctx,
780 GLfloat t,
781 GLuint dst, GLuint out, GLuint in,
782 GLboolean force_boundary )
783{
784 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
785
786 if (VB->ColorPtr[1]) {
787 assert(VB->ColorPtr[1]->stride == 4 * sizeof(GLfloat));
788
789 INTERP_4F( t,
790 VB->ColorPtr[1]->data[dst],
791 VB->ColorPtr[1]->data[out],
792 VB->ColorPtr[1]->data[in] );
793
794 if (VB->SecondaryColorPtr[1]) {
795 INTERP_3F( t,
796 VB->SecondaryColorPtr[1]->data[dst],
797 VB->SecondaryColorPtr[1]->data[out],
798 VB->SecondaryColorPtr[1]->data[in] );
Keith Whitwellfabb9732003-12-21 17:54:31 +0000799 }
800 }
Keith Whitwell58822572004-01-05 15:24:53 +0000801 else if (VB->IndexPtr[1]) {
802 VB->IndexPtr[1]->data[dst][0] = LINTERP( t,
803 VB->IndexPtr[1]->data[out][0],
804 VB->IndexPtr[1]->data[in][0] );
805 }
Keith Whitwellfabb9732003-12-21 17:54:31 +0000806
Keith Whitwell79073402004-01-05 09:43:42 +0000807 if (VB->EdgeFlag) {
808 VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary;
809 }
810
811 generic_interp(ctx, t, dst, out, in, force_boundary);
Keith Whitwellfabb9732003-12-21 17:54:31 +0000812}
813
Keith Whitwell79073402004-01-05 09:43:42 +0000814static void generic_copy_pv_extras( GLcontext *ctx,
815 GLuint dst, GLuint src )
816{
817 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
818
819 if (VB->ColorPtr[1]) {
820 COPY_4FV( VB->ColorPtr[1]->data[dst],
821 VB->ColorPtr[1]->data[src] );
822
823 if (VB->SecondaryColorPtr[1]) {
824 COPY_4FV( VB->SecondaryColorPtr[1]->data[dst],
825 VB->SecondaryColorPtr[1]->data[src] );
826 }
827 }
Keith Whitwell58822572004-01-05 15:24:53 +0000828 else if (VB->IndexPtr[1]) {
829 VB->IndexPtr[1]->data[dst][0] = VB->IndexPtr[1]->data[src][0];
830 }
Keith Whitwell79073402004-01-05 09:43:42 +0000831
832 _tnl_copy_pv(ctx, dst, src);
833}
Keith Whitwellfabb9732003-12-21 17:54:31 +0000834
835
836
837
838
839
840/***********************************************************************
841 * Build codegen functions or return generic ones:
842 */
843
844
845static void choose_emit_func( GLcontext *ctx,
846 GLuint start, GLuint end,
Keith Whitwell79073402004-01-05 09:43:42 +0000847 void *dest )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000848{
Keith Whitwell79073402004-01-05 09:43:42 +0000849 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
850 vtx->emit = generic_emit;
851 vtx->emit( ctx, start, end, dest );
Keith Whitwellfabb9732003-12-21 17:54:31 +0000852}
853
854
855static void choose_interp_func( GLcontext *ctx,
856 GLfloat t,
857 GLuint edst, GLuint eout, GLuint ein,
858 GLboolean force_boundary )
859{
Keith Whitwell79073402004-01-05 09:43:42 +0000860 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
861
862 if (vtx->need_extras &&
863 (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
864 vtx->interp = generic_interp_extras;
865 } else {
866 vtx->interp = generic_interp;
867 }
868
869 vtx->interp( ctx, t, edst, eout, ein, force_boundary );
Keith Whitwellfabb9732003-12-21 17:54:31 +0000870}
871
872
Keith Whitwell79073402004-01-05 09:43:42 +0000873static void choose_copy_pv_func( GLcontext *ctx, GLuint edst, GLuint esrc )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000874{
Keith Whitwell79073402004-01-05 09:43:42 +0000875 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
876
877 if (vtx->need_extras &&
878 (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
879 vtx->copy_pv = generic_copy_pv_extras;
880 } else {
881 vtx->copy_pv = generic_copy_pv;
882 }
883
884 vtx->copy_pv( ctx, edst, esrc );
Keith Whitwellfabb9732003-12-21 17:54:31 +0000885}
886
887
888/***********************************************************************
889 * Public entrypoints, mostly dispatch to the above:
890 */
891
Keith Whitwellfabb9732003-12-21 17:54:31 +0000892
893/* Interpolate between two vertices to produce a third:
894 */
895void _tnl_interp( GLcontext *ctx,
896 GLfloat t,
897 GLuint edst, GLuint eout, GLuint ein,
898 GLboolean force_boundary )
899{
Keith Whitwell79073402004-01-05 09:43:42 +0000900 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
901 vtx->interp( ctx, t, edst, eout, ein, force_boundary );
Keith Whitwellfabb9732003-12-21 17:54:31 +0000902}
903
904/* Copy colors from one vertex to another:
905 */
Keith Whitwell79073402004-01-05 09:43:42 +0000906void _tnl_copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000907{
Keith Whitwell79073402004-01-05 09:43:42 +0000908 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
909 vtx->copy_pv( ctx, edst, esrc );
Keith Whitwellfabb9732003-12-21 17:54:31 +0000910}
911
912
913/* Extract a named attribute from a hardware vertex. Will have to
914 * reverse any viewport transformation, swizzling or other conversions
915 * which may have been applied:
916 */
Keith Whitwell79073402004-01-05 09:43:42 +0000917void _tnl_get_attr( GLcontext *ctx, const void *vin,
918 GLenum attr, GLfloat *dest )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000919{
Keith Whitwell79073402004-01-05 09:43:42 +0000920 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
921 const struct tnl_clipspace_attr *a = vtx->attr;
922 int attr_count = vtx->attr_count;
923 int j;
924
925 for (j = 0; j < attr_count; j++) {
Karl Schultzc6c4cd82004-01-13 01:11:09 +0000926 if (a[j].attrib == (int)attr) {
Keith Whitwell44d4a8f2004-01-06 00:18:03 +0000927 a[j].extract( &a[j], dest, (GLubyte *)vin + a[j].vertoffset );
Keith Whitwell79073402004-01-05 09:43:42 +0000928 return;
929 }
930 }
931
932 /* Else return the value from ctx->Current
933 */
Brian Paul3663c0f2004-01-15 00:29:51 +0000934 _mesa_memcpy( dest, ctx->Current.Attrib[attr], 4*sizeof(GLfloat));
Keith Whitwell79073402004-01-05 09:43:42 +0000935}
936
937void *_tnl_get_vertex( GLcontext *ctx, GLuint nr )
938{
939 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
940
941 return vtx->vertex_buf + nr * vtx->vertex_size;
942}
943
944void _tnl_invalidate_vertex_state( GLcontext *ctx, GLuint new_state )
945{
946 if (new_state & (_DD_NEW_TRI_LIGHT_TWOSIDE|_DD_NEW_TRI_UNFILLED) ) {
947 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
948 vtx->new_inputs = ~0;
949 vtx->interp = choose_interp_func;
950 vtx->copy_pv = choose_copy_pv_func;
951 }
Keith Whitwellfabb9732003-12-21 17:54:31 +0000952}
953
954
Keith Whitwell79073402004-01-05 09:43:42 +0000955GLuint _tnl_install_attrs( GLcontext *ctx, const struct tnl_attr_map *map,
Keith Whitwell58822572004-01-05 15:24:53 +0000956 GLuint nr, const GLfloat *vp,
957 GLuint unpacked_size )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000958{
Keith Whitwell79073402004-01-05 09:43:42 +0000959 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
960 int offset = 0;
Karl Schultzc6c4cd82004-01-13 01:11:09 +0000961 GLuint i;
Keith Whitwellfabb9732003-12-21 17:54:31 +0000962
Keith Whitwell79073402004-01-05 09:43:42 +0000963 assert(nr < _TNL_ATTRIB_MAX);
964 assert(nr == 0 || map[0].attrib == VERT_ATTRIB_POS);
Keith Whitwellfabb9732003-12-21 17:54:31 +0000965
966 vtx->attr_count = nr;
Keith Whitwell79073402004-01-05 09:43:42 +0000967 vtx->emit = choose_emit_func;
968 vtx->interp = choose_interp_func;
969 vtx->copy_pv = choose_copy_pv_func;
970 vtx->new_inputs = ~0;
Keith Whitwellfabb9732003-12-21 17:54:31 +0000971
972 for (i = 0; i < nr; i++) {
Keith Whitwell79073402004-01-05 09:43:42 +0000973 GLuint format = map[i].format;
Keith Whitwellfabb9732003-12-21 17:54:31 +0000974 vtx->attr[i].attrib = map[i].attrib;
Keith Whitwellfabb9732003-12-21 17:54:31 +0000975 vtx->attr[i].vp = vp;
Keith Whitwell79073402004-01-05 09:43:42 +0000976 vtx->attr[i].insert = format_info[format].insert;
977 vtx->attr[i].extract = format_info[format].extract;
978 vtx->attr[i].vertattrsize = format_info[format].attrsize;
Keith Whitwell16f54212004-01-05 15:55:01 +0000979
980 if (unpacked_size)
Keith Whitwell58822572004-01-05 15:24:53 +0000981 vtx->attr[i].vertoffset = map[i].offset;
Keith Whitwell16f54212004-01-05 15:55:01 +0000982 else
983 vtx->attr[i].vertoffset = offset;
984
Keith Whitwell44d4a8f2004-01-06 00:18:03 +0000985/* fprintf(stderr, "%d: %s offset %d\n", i, */
986/* format_info[format].name, vtx->attr[i].vertoffset); */
987
Keith Whitwell16f54212004-01-05 15:55:01 +0000988 offset += format_info[format].attrsize;
Keith Whitwellfabb9732003-12-21 17:54:31 +0000989 }
Keith Whitwell79073402004-01-05 09:43:42 +0000990
Keith Whitwell58822572004-01-05 15:24:53 +0000991 if (unpacked_size)
992 vtx->vertex_size = unpacked_size;
993 else
994 vtx->vertex_size = offset;
Keith Whitwell79073402004-01-05 09:43:42 +0000995
Keith Whitwell58822572004-01-05 15:24:53 +0000996 assert(vtx->vertex_size <= vtx->max_vertex_size);
997
Keith Whitwell79073402004-01-05 09:43:42 +0000998 return vtx->vertex_size;
Keith Whitwellfabb9732003-12-21 17:54:31 +0000999}
1000
1001
1002
Keith Whitwell79073402004-01-05 09:43:42 +00001003void _tnl_invalidate_vertices( GLcontext *ctx, GLuint newinputs )
Keith Whitwellfabb9732003-12-21 17:54:31 +00001004{
Keith Whitwell79073402004-01-05 09:43:42 +00001005 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1006 vtx->new_inputs |= newinputs;
Keith Whitwellfabb9732003-12-21 17:54:31 +00001007}
1008
1009
Keith Whitwell79073402004-01-05 09:43:42 +00001010
1011void _tnl_build_vertices( GLcontext *ctx,
1012 GLuint start,
1013 GLuint count,
1014 GLuint newinputs )
Keith Whitwellfabb9732003-12-21 17:54:31 +00001015{
Keith Whitwell79073402004-01-05 09:43:42 +00001016 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1017 GLuint stride = vtx->vertex_size;
1018 GLubyte *v = ((GLubyte *)vtx->vertex_buf + (start*stride));
Keith Whitwellfabb9732003-12-21 17:54:31 +00001019
Keith Whitwell79073402004-01-05 09:43:42 +00001020 newinputs |= vtx->new_inputs;
1021 vtx->new_inputs = 0;
Keith Whitwellfabb9732003-12-21 17:54:31 +00001022
Keith Whitwell79073402004-01-05 09:43:42 +00001023 if (newinputs)
1024 vtx->emit( ctx, start, count, v );
Keith Whitwellfabb9732003-12-21 17:54:31 +00001025}
1026
Keith Whitwell79073402004-01-05 09:43:42 +00001027
1028void *_tnl_emit_vertices_to_buffer( GLcontext *ctx,
1029 GLuint start,
1030 GLuint count,
1031 void *dest )
Keith Whitwellfabb9732003-12-21 17:54:31 +00001032{
Keith Whitwell79073402004-01-05 09:43:42 +00001033 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1034 vtx->emit( ctx, start, count, dest );
Keith Whitwell58822572004-01-05 15:24:53 +00001035 return (void *)((GLubyte *)dest + vtx->vertex_size * (count - start));
Keith Whitwellfabb9732003-12-21 17:54:31 +00001036}
1037
Keith Whitwell79073402004-01-05 09:43:42 +00001038
1039void _tnl_init_vertices( GLcontext *ctx,
1040 GLuint vb_size,
1041 GLuint max_vertex_size )
1042{
1043 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1044
Keith Whitwell58822572004-01-05 15:24:53 +00001045 _tnl_install_attrs( ctx, 0, 0, 0, 0 );
Keith Whitwell79073402004-01-05 09:43:42 +00001046
1047 vtx->need_extras = GL_TRUE;
Keith Whitwell58822572004-01-05 15:24:53 +00001048 if (max_vertex_size > vtx->max_vertex_size) {
1049 _tnl_free_vertices( ctx );
1050 vtx->max_vertex_size = max_vertex_size;
1051 vtx->vertex_buf = (GLubyte *)ALIGN_MALLOC(vb_size * max_vertex_size, 32 );
1052 }
Keith Whitwell79073402004-01-05 09:43:42 +00001053}
1054
1055
1056void _tnl_free_vertices( GLcontext *ctx )
1057{
1058 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1059 if (vtx->vertex_buf) {
1060 ALIGN_FREE(vtx->vertex_buf);
1061 vtx->vertex_buf = 0;
1062 }
1063}