blob: 0adbfede2d5321946bea10f6602b8cb95d983ee3 [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 Whitwellfabb9732003-12-21 17:54:31 +000046
Brian Paulfde4c532004-03-13 18:27:06 +000047
48/*
49 * These functions take the NDC coordinates pointed to by 'in', apply the
50 * NDC->Viewport mapping and store the results at 'v'.
51 */
52
53static void
54insert_4f_viewport_4( const struct tnl_clipspace_attr *a, GLubyte *v,
55 const GLfloat *in )
Keith Whitwellfabb9732003-12-21 17:54:31 +000056{
57 GLfloat *out = (GLfloat *)v;
58 const GLfloat * const vp = a->vp;
59
60 out[0] = vp[0] * in[0] + vp[12];
61 out[1] = vp[5] * in[1] + vp[13];
62 out[2] = vp[10] * in[2] + vp[14];
63 out[3] = in[3];
64}
65
Keith Whitwell58822572004-01-05 15:24:53 +000066static void insert_4f_viewport_3( const struct tnl_clipspace_attr *a, GLubyte *v,
67 const GLfloat *in )
68{
69 GLfloat *out = (GLfloat *)v;
70 const GLfloat * const vp = a->vp;
71
72 out[0] = vp[0] * in[0] + vp[12];
73 out[1] = vp[5] * in[1] + vp[13];
74 out[2] = vp[10] * in[2] + vp[14];
75 out[3] = 1;
76}
77
78static void insert_4f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
79 const GLfloat *in )
80{
81 GLfloat *out = (GLfloat *)v;
82 const GLfloat * const vp = a->vp;
83
84 out[0] = vp[0] * in[0] + vp[12];
85 out[1] = vp[5] * in[1] + vp[13];
86 out[2] = vp[14];
87 out[3] = 1;
88}
89
90static void insert_4f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
91 const GLfloat *in )
92{
93 GLfloat *out = (GLfloat *)v;
94 const GLfloat * const vp = a->vp;
95
96 out[0] = vp[0] * in[0] + vp[12];
97 out[1] = vp[13];
98 out[2] = vp[14];
99 out[3] = 1;
100}
101
102static void insert_3f_viewport_3( const struct tnl_clipspace_attr *a, GLubyte *v,
Keith Whitwellfabb9732003-12-21 17:54:31 +0000103 const GLfloat *in )
104{
105 GLfloat *out = (GLfloat *)v;
106 const GLfloat * const vp = a->vp;
107
108 out[0] = vp[0] * in[0] + vp[12];
109 out[1] = vp[5] * in[1] + vp[13];
110 out[2] = vp[10] * in[2] + vp[14];
111}
112
Keith Whitwell58822572004-01-05 15:24:53 +0000113static void insert_3f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
114 const GLfloat *in )
115{
116 GLfloat *out = (GLfloat *)v;
117 const GLfloat * const vp = a->vp;
118
119 out[0] = vp[0] * in[0] + vp[12];
120 out[1] = vp[5] * in[1] + vp[13];
121 out[2] = vp[10] * in[2] + vp[14];
122}
123
124static void insert_3f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
125 const GLfloat *in )
126{
127 GLfloat *out = (GLfloat *)v;
128 const GLfloat * const vp = a->vp;
129
130 out[0] = vp[0] * in[0] + vp[12];
131 out[1] = vp[13];
132 out[2] = vp[14];
133}
134
135static void insert_2f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v,
Keith Whitwellfabb9732003-12-21 17:54:31 +0000136 const GLfloat *in )
137{
138 GLfloat *out = (GLfloat *)v;
139 const GLfloat * const vp = a->vp;
140
141 out[0] = vp[0] * in[0] + vp[12];
142 out[1] = vp[5] * in[1] + vp[13];
143}
144
Keith Whitwell58822572004-01-05 15:24:53 +0000145static void insert_2f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v,
146 const GLfloat *in )
147{
148 GLfloat *out = (GLfloat *)v;
149 const GLfloat * const vp = a->vp;
150
151 out[0] = vp[0] * in[0] + vp[12];
152 out[1] = vp[13];
153}
Keith Whitwellfabb9732003-12-21 17:54:31 +0000154
Keith Whitwell58822572004-01-05 15:24:53 +0000155
Brian Paulfde4c532004-03-13 18:27:06 +0000156/*
157 * These functions do the same as above, except for the viewport mapping.
158 */
159
Keith Whitwell58822572004-01-05 15:24:53 +0000160static void insert_4f_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
Keith Whitwellfabb9732003-12-21 17:54:31 +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] = in[3];
168}
169
Keith Whitwell58822572004-01-05 15:24:53 +0000170static void insert_4f_3( 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] = in[2];
177 out[3] = 1;
178}
179
Keith Whitwell58822572004-01-05 15:24:53 +0000180static void insert_4f_2( 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] = in[1];
186 out[2] = 0;
187 out[3] = 1;
188}
189
Keith Whitwell58822572004-01-05 15:24:53 +0000190static void insert_4f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
Keith Whitwell79073402004-01-05 09:43:42 +0000191{
192 GLfloat *out = (GLfloat *)(v);
193
194 out[0] = in[0];
195 out[1] = 0;
196 out[2] = 0;
197 out[3] = 1;
198}
199
Keith Whitwell58822572004-01-05 15:24:53 +0000200static void insert_3f_xyw_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
201{
202 GLfloat *out = (GLfloat *)(v);
203
204 out[0] = in[0];
205 out[1] = in[1];
206 out[2] = in[3];
207}
208
209static void insert_3f_xyw_err( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
210{
211 abort();
212}
213
214static void insert_3f_3( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
215{
216 GLfloat *out = (GLfloat *)(v);
217
218 out[0] = in[0];
219 out[1] = in[1];
220 out[2] = in[2];
221}
222
223static void insert_3f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
224{
225 GLfloat *out = (GLfloat *)(v);
226
227 out[0] = in[0];
228 out[1] = in[1];
229 out[2] = 0;
230}
231
232static void insert_3f_1( 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] = 0;
238 out[2] = 0;
239}
240
241
242static void insert_2f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
243{
244 GLfloat *out = (GLfloat *)(v);
245
246 out[0] = in[0];
247 out[1] = in[1];
248}
249
250static void insert_2f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
251{
252 GLfloat *out = (GLfloat *)(v);
253
254 out[0] = in[0];
255 out[1] = 0;
256}
257
258static void insert_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in )
259{
260 GLfloat *out = (GLfloat *)(v);
261
262 out[0] = in[0];
263}
264
265static void insert_4chan_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v,
Keith Whitwell79073402004-01-05 09:43:42 +0000266 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 UNCLAMPED_FLOAT_TO_CHAN(c[3], in[3]);
273}
274
Keith Whitwell58822572004-01-05 15:24:53 +0000275static void insert_4chan_4f_rgba_3( 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 UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]);
282 c[3] = CHAN_MAX;
283}
284
285static void insert_4chan_4f_rgba_2( 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 UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]);
291 c[2] = 0;
292 c[3] = CHAN_MAX;
293}
294
295static void insert_4chan_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v,
296 const GLfloat *in )
297{
298 GLchan *c = (GLchan *)v;
299 UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]);
300 c[1] = 0;
301 c[2] = 0;
302 c[3] = CHAN_MAX;
303}
304
305static void insert_4ub_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v,
Keith Whitwellfabb9732003-12-21 17:54:31 +0000306 const GLfloat *in )
307{
308 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
309 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
310 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
311 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
312}
313
Keith Whitwell58822572004-01-05 15:24:53 +0000314static void insert_4ub_4f_rgba_3( const struct tnl_clipspace_attr *a, GLubyte *v,
315 const GLfloat *in )
316{
317 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
318 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
319 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
320 v[3] = 0xff;
321}
322
323static void insert_4ub_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v,
324 const GLfloat *in )
325{
326 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
327 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
328 v[2] = 0;
329 v[3] = 0xff;
330}
331
332static void insert_4ub_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v,
333 const GLfloat *in )
334{
335 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
336 v[1] = 0;
337 v[2] = 0;
338 v[3] = 0xff;
339}
340
341static void insert_4ub_4f_bgra_4( const struct tnl_clipspace_attr *a, GLubyte *v,
Keith Whitwellfabb9732003-12-21 17:54:31 +0000342 const GLfloat *in )
343{
344 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
345 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
346 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
347 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]);
348}
349
Keith Whitwell58822572004-01-05 15:24:53 +0000350static void insert_4ub_4f_bgra_3( const struct tnl_clipspace_attr *a, GLubyte *v,
351 const GLfloat *in )
352{
353 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
354 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
355 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
356 v[3] = 0xff;
357}
358
359static void insert_4ub_4f_bgra_2( const struct tnl_clipspace_attr *a, GLubyte *v,
360 const GLfloat *in )
361{
362 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
363 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
364 v[0] = 0;
365 v[3] = 0xff;
366}
367
368static void insert_4ub_4f_bgra_1( const struct tnl_clipspace_attr *a, GLubyte *v,
369 const GLfloat *in )
370{
371 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
372 v[1] = 0;
373 v[0] = 0;
374 v[3] = 0xff;
375}
376
377static void insert_3ub_3f_rgb_3( const struct tnl_clipspace_attr *a, GLubyte *v,
Keith Whitwellfabb9732003-12-21 17:54:31 +0000378 const GLfloat *in )
379{
380 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
381 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
382 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]);
383}
384
Keith Whitwell58822572004-01-05 15:24:53 +0000385static void insert_3ub_3f_rgb_2( const struct tnl_clipspace_attr *a, GLubyte *v,
Keith Whitwellfabb9732003-12-21 17:54:31 +0000386 const GLfloat *in )
387{
Keith Whitwell58822572004-01-05 15:24:53 +0000388 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
389 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
390 v[2] = 0;
391}
392
393static void insert_3ub_3f_rgb_1( const struct tnl_clipspace_attr *a, GLubyte *v,
394 const GLfloat *in )
395{
396 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
397 v[1] = 0;
398 v[2] = 0;
399}
400
401static void insert_3ub_3f_bgr_3( const struct tnl_clipspace_attr *a, GLubyte *v,
402 const GLfloat *in )
403{
Keith Whitwellfabb9732003-12-21 17:54:31 +0000404 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
405 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
406 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]);
407}
408
Keith Whitwell58822572004-01-05 15:24:53 +0000409static void insert_3ub_3f_bgr_2( const struct tnl_clipspace_attr *a, GLubyte *v,
410 const GLfloat *in )
411{
412 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
413 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]);
414 v[0] = 0;
415}
416
417static void insert_3ub_3f_bgr_1( const struct tnl_clipspace_attr *a, GLubyte *v,
418 const GLfloat *in )
419{
420 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]);
421 v[1] = 0;
Keith Whitwellef167c62004-01-26 21:34:28 +0000422 v[0] = 0;
Keith Whitwell58822572004-01-05 15:24:53 +0000423}
424
425
426static void insert_1ub_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v,
Keith Whitwellfabb9732003-12-21 17:54:31 +0000427 const GLfloat *in )
428{
429 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]);
430}
431
432
433/***********************************************************************
434 * Functions to perform the reverse operations to the above, for
435 * swrast translation and clip-interpolation.
436 *
437 * Currently always extracts a full 4 floats.
438 */
439
Keith Whitwell79073402004-01-05 09:43:42 +0000440static void extract_4f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out,
Keith Whitwell58822572004-01-05 15:24:53 +0000441 const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000442{
443 const GLfloat *in = (const GLfloat *)v;
444 const GLfloat * const vp = a->vp;
445
Keith Whitwellef167c62004-01-26 21:34:28 +0000446 /* Although included for completeness, the position coordinate is
447 * usually handled differently during clipping.
448 */
Keith Whitwellfabb9732003-12-21 17:54:31 +0000449 out[0] = (in[0] - vp[12]) / vp[0];
450 out[1] = (in[1] - vp[13]) / vp[5];
451 out[2] = (in[2] - vp[14]) / vp[10];
452 out[3] = in[3];
453}
454
Keith Whitwell79073402004-01-05 09:43:42 +0000455static void extract_3f_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] = (in[2] - vp[14]) / vp[10];
464 out[3] = 1;
465}
466
467
Keith Whitwell79073402004-01-05 09:43:42 +0000468static void extract_2f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out,
Keith Whitwell58822572004-01-05 15:24:53 +0000469 const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000470{
471 const GLfloat *in = (const GLfloat *)v;
472 const GLfloat * const vp = a->vp;
473
474 out[0] = (in[0] - vp[12]) / vp[0];
475 out[1] = (in[1] - vp[13]) / vp[5];
476 out[2] = 0;
477 out[3] = 1;
478}
479
480
Keith Whitwell58822572004-01-05 15:24:53 +0000481static void extract_4f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000482{
483 const GLfloat *in = (const GLfloat *)v;
484
485 out[0] = in[0];
486 out[1] = in[1];
487 out[2] = in[2];
488 out[3] = in[3];
489}
490
Keith Whitwell58822572004-01-05 15:24:53 +0000491static void extract_3f_xyw( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000492{
493 const GLfloat *in = (const GLfloat *)v;
494
495 out[0] = in[0];
496 out[1] = in[1];
Keith Whitwellbacd9d12004-01-30 11:16:12 +0000497 out[2] = 0;
498 out[3] = in[2];
Keith Whitwellfabb9732003-12-21 17:54:31 +0000499}
500
501
Keith Whitwell58822572004-01-05 15:24:53 +0000502static void extract_3f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000503{
504 const GLfloat *in = (const GLfloat *)v;
505
506 out[0] = in[0];
507 out[1] = in[1];
508 out[2] = in[2];
509 out[3] = 1;
510}
511
512
Keith Whitwell58822572004-01-05 15:24:53 +0000513static void extract_2f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000514{
515 const GLfloat *in = (const GLfloat *)v;
516
517 out[0] = in[0];
518 out[1] = in[1];
519 out[2] = 0;
520 out[3] = 1;
521}
522
Keith Whitwell58822572004-01-05 15:24:53 +0000523static void extract_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000524{
525 const GLfloat *in = (const GLfloat *)v;
526
527 out[0] = in[0];
528 out[1] = 0;
529 out[2] = 0;
530 out[3] = 1;
531}
532
Keith Whitwell79073402004-01-05 09:43:42 +0000533static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out,
Keith Whitwell58822572004-01-05 15:24:53 +0000534 const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000535{
Keith Whitwell79073402004-01-05 09:43:42 +0000536 GLchan *c = (GLchan *)v;
537
538 out[0] = CHAN_TO_FLOAT(c[0]);
539 out[1] = CHAN_TO_FLOAT(c[1]);
540 out[2] = CHAN_TO_FLOAT(c[2]);
541 out[3] = CHAN_TO_FLOAT(c[3]);
Keith Whitwellfabb9732003-12-21 17:54:31 +0000542}
543
Keith Whitwell79073402004-01-05 09:43:42 +0000544static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out,
Keith Whitwell58822572004-01-05 15:24:53 +0000545 const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000546{
Keith Whitwell79073402004-01-05 09:43:42 +0000547 out[0] = UBYTE_TO_FLOAT(v[0]);
548 out[1] = UBYTE_TO_FLOAT(v[1]);
549 out[2] = UBYTE_TO_FLOAT(v[2]);
550 out[3] = UBYTE_TO_FLOAT(v[3]);
Keith Whitwellfabb9732003-12-21 17:54:31 +0000551}
552
Keith Whitwell79073402004-01-05 09:43:42 +0000553static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr *a, GLfloat *out,
Keith Whitwell58822572004-01-05 15:24:53 +0000554 const GLubyte *v )
Keith Whitwell79073402004-01-05 09:43:42 +0000555{
556 out[2] = UBYTE_TO_FLOAT(v[0]);
557 out[1] = UBYTE_TO_FLOAT(v[1]);
558 out[0] = UBYTE_TO_FLOAT(v[2]);
559 out[3] = UBYTE_TO_FLOAT(v[3]);
560}
561
562static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr *a, GLfloat *out,
Keith Whitwell58822572004-01-05 15:24:53 +0000563 const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000564{
Keith Whitwell79073402004-01-05 09:43:42 +0000565 out[0] = UBYTE_TO_FLOAT(v[0]);
566 out[1] = UBYTE_TO_FLOAT(v[1]);
567 out[2] = UBYTE_TO_FLOAT(v[2]);
Keith Whitwellfabb9732003-12-21 17:54:31 +0000568 out[3] = 1;
569}
570
Keith Whitwell79073402004-01-05 09:43:42 +0000571static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr *a, GLfloat *out,
Keith Whitwell58822572004-01-05 15:24:53 +0000572 const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000573{
Keith Whitwell79073402004-01-05 09:43:42 +0000574 out[2] = UBYTE_TO_FLOAT(v[0]);
575 out[1] = UBYTE_TO_FLOAT(v[1]);
576 out[0] = UBYTE_TO_FLOAT(v[2]);
Keith Whitwellfabb9732003-12-21 17:54:31 +0000577 out[3] = 1;
578}
579
Keith Whitwell58822572004-01-05 15:24:53 +0000580static void extract_1ub_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000581{
Keith Whitwell79073402004-01-05 09:43:42 +0000582 out[0] = UBYTE_TO_FLOAT(v[0]);
Keith Whitwellfabb9732003-12-21 17:54:31 +0000583 out[1] = 0;
584 out[2] = 0;
585 out[3] = 1;
586}
587
Keith Whitwell79073402004-01-05 09:43:42 +0000588
Keith Whitwell009aa3e2004-06-30 11:48:21 +0000589static struct {
Keith Whitwell58822572004-01-05 15:24:53 +0000590 const char *name;
Keith Whitwell79073402004-01-05 09:43:42 +0000591 extract_func extract;
Keith Whitwell58822572004-01-05 15:24:53 +0000592 insert_func insert[4];
Brian Paulfde4c532004-03-13 18:27:06 +0000593 const GLuint attrsize;
Keith Whitwell79073402004-01-05 09:43:42 +0000594} format_info[EMIT_MAX] = {
595
Keith Whitwell58822572004-01-05 15:24:53 +0000596 { "1f",
597 extract_1f,
598 { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 },
Keith Whitwell79073402004-01-05 09:43:42 +0000599 sizeof(GLfloat) },
600
Keith Whitwell58822572004-01-05 15:24:53 +0000601 { "2f",
602 extract_2f,
603 { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 },
Keith Whitwell79073402004-01-05 09:43:42 +0000604 2 * sizeof(GLfloat) },
605
Keith Whitwell58822572004-01-05 15:24:53 +0000606 { "3f",
607 extract_3f,
608 { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 },
Keith Whitwell79073402004-01-05 09:43:42 +0000609 3 * sizeof(GLfloat) },
610
Keith Whitwell58822572004-01-05 15:24:53 +0000611 { "4f",
612 extract_4f,
613 { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 },
Keith Whitwell79073402004-01-05 09:43:42 +0000614 4 * sizeof(GLfloat) },
615
Keith Whitwell58822572004-01-05 15:24:53 +0000616 { "2f_viewport",
617 extract_2f_viewport,
618 { insert_2f_viewport_1, insert_2f_viewport_2, insert_2f_viewport_2,
619 insert_2f_viewport_2 },
Keith Whitwell79073402004-01-05 09:43:42 +0000620 2 * sizeof(GLfloat) },
621
Keith Whitwell58822572004-01-05 15:24:53 +0000622 { "3f_viewport",
623 extract_3f_viewport,
624 { insert_3f_viewport_1, insert_3f_viewport_2, insert_3f_viewport_3,
625 insert_3f_viewport_3 },
Keith Whitwell79073402004-01-05 09:43:42 +0000626 3 * sizeof(GLfloat) },
627
Keith Whitwell58822572004-01-05 15:24:53 +0000628 { "4f_viewport",
629 extract_4f_viewport,
630 { insert_4f_viewport_1, insert_4f_viewport_2, insert_4f_viewport_3,
631 insert_4f_viewport_4 },
Keith Whitwell79073402004-01-05 09:43:42 +0000632 4 * sizeof(GLfloat) },
633
Keith Whitwell58822572004-01-05 15:24:53 +0000634 { "3f_xyw",
635 extract_3f_xyw,
636 { insert_3f_xyw_err, insert_3f_xyw_err, insert_3f_xyw_err,
637 insert_3f_xyw_4 },
Keith Whitwell79073402004-01-05 09:43:42 +0000638 3 * sizeof(GLfloat) },
639
Keith Whitwell58822572004-01-05 15:24:53 +0000640 { "1ub_1f",
641 extract_1ub_1f,
642 { insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1 },
Keith Whitwell79073402004-01-05 09:43:42 +0000643 sizeof(GLubyte) },
644
Keith Whitwell58822572004-01-05 15:24:53 +0000645 { "3ub_3f_rgb",
646 extract_3ub_3f_rgb,
647 { insert_3ub_3f_rgb_1, insert_3ub_3f_rgb_2, insert_3ub_3f_rgb_3,
648 insert_3ub_3f_rgb_3 },
Keith Whitwell79073402004-01-05 09:43:42 +0000649 3 * sizeof(GLubyte) },
650
Keith Whitwell58822572004-01-05 15:24:53 +0000651 { "3ub_3f_bgr",
652 extract_3ub_3f_bgr,
653 { insert_3ub_3f_bgr_1, insert_3ub_3f_bgr_2, insert_3ub_3f_bgr_3,
654 insert_3ub_3f_bgr_3 },
Keith Whitwell79073402004-01-05 09:43:42 +0000655 3 * sizeof(GLubyte) },
656
Keith Whitwell58822572004-01-05 15:24:53 +0000657 { "4ub_4f_rgba",
658 extract_4ub_4f_rgba,
659 { insert_4ub_4f_rgba_1, insert_4ub_4f_rgba_2, insert_4ub_4f_rgba_3,
660 insert_4ub_4f_rgba_4 },
Keith Whitwell79073402004-01-05 09:43:42 +0000661 4 * sizeof(GLubyte) },
662
Keith Whitwell58822572004-01-05 15:24:53 +0000663 { "4ub_4f_bgra",
664 extract_4ub_4f_bgra,
665 { insert_4ub_4f_bgra_1, insert_4ub_4f_bgra_2, insert_4ub_4f_bgra_3,
666 insert_4ub_4f_bgra_4 },
Keith Whitwell79073402004-01-05 09:43:42 +0000667 4 * sizeof(GLubyte) },
668
Keith Whitwell58822572004-01-05 15:24:53 +0000669 { "4chan_4f_rgba",
670 extract_4chan_4f_rgba,
671 { insert_4chan_4f_rgba_1, insert_4chan_4f_rgba_2, insert_4chan_4f_rgba_3,
672 insert_4chan_4f_rgba_4 },
Keith Whitwell4d36f332004-01-21 15:31:46 +0000673 4 * sizeof(GLchan) },
674
675 { "pad",
676 0,
677 { 0, 0, 0, 0 },
678 0 }
Keith Whitwell79073402004-01-05 09:43:42 +0000679
680};
681
682
Keith Whitwellfabb9732003-12-21 17:54:31 +0000683/***********************************************************************
684 * Generic (non-codegen) functions for whole vertices or groups of
685 * vertices
686 */
687
688static void generic_emit( GLcontext *ctx,
689 GLuint start, GLuint end,
Keith Whitwell79073402004-01-05 09:43:42 +0000690 void *dest )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000691{
Keith Whitwell79073402004-01-05 09:43:42 +0000692 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
693 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
694 struct tnl_clipspace_attr *a = vtx->attr;
Keith Whitwell58822572004-01-05 15:24:53 +0000695 GLubyte *v = (GLubyte *)dest;
Karl Schultzc6c4cd82004-01-13 01:11:09 +0000696 GLuint i, j;
Brian Paulfde4c532004-03-13 18:27:06 +0000697 const GLuint count = vtx->attr_count;
Keith Whitwell79073402004-01-05 09:43:42 +0000698 GLuint stride;
Keith Whitwellfabb9732003-12-21 17:54:31 +0000699
Keith Whitwell79073402004-01-05 09:43:42 +0000700 for (j = 0; j < count; j++) {
701 GLvector4f *vptr = VB->AttribPtr[a[j].attrib];
702 a[j].inputstride = vptr->stride;
Keith Whitwell44d4a8f2004-01-06 00:18:03 +0000703 a[j].inputptr = ((GLubyte *)vptr->data) + start * vptr->stride;
Keith Whitwell58822572004-01-05 15:24:53 +0000704 a[j].emit = a[j].insert[vptr->size - 1];
Keith Whitwellfabb9732003-12-21 17:54:31 +0000705 }
706
Keith Whitwell79073402004-01-05 09:43:42 +0000707 end -= start;
708 stride = vtx->vertex_size;
709
Keith Whitwellfabb9732003-12-21 17:54:31 +0000710 for (i = 0 ; i < end ; i++, v += stride) {
Keith Whitwell79073402004-01-05 09:43:42 +0000711 for (j = 0; j < count; j++) {
Keith Whitwell58822572004-01-05 15:24:53 +0000712 GLfloat *in = (GLfloat *)a[j].inputptr;
713 a[j].inputptr += a[j].inputstride;
714 a[j].emit( &a[j], v + a[j].vertoffset, in );
Keith Whitwellfabb9732003-12-21 17:54:31 +0000715 }
716 }
717}
718
719
720static void generic_interp( GLcontext *ctx,
721 GLfloat t,
722 GLuint edst, GLuint eout, GLuint ein,
723 GLboolean force_boundary )
724{
Keith Whitwell79073402004-01-05 09:43:42 +0000725 TNLcontext *tnl = TNL_CONTEXT(ctx);
726 struct vertex_buffer *VB = &tnl->vb;
727 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
Brian Paulfde4c532004-03-13 18:27:06 +0000728 const GLubyte *vin = vtx->vertex_buf + ein * vtx->vertex_size;
729 const GLubyte *vout = vtx->vertex_buf + eout * vtx->vertex_size;
Keith Whitwell58822572004-01-05 15:24:53 +0000730 GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size;
Keith Whitwell79073402004-01-05 09:43:42 +0000731 const struct tnl_clipspace_attr *a = vtx->attr;
Brian Paulfde4c532004-03-13 18:27:06 +0000732 const GLuint attr_count = vtx->attr_count;
733 GLuint j;
Keith Whitwell79073402004-01-05 09:43:42 +0000734
735 if (tnl->NeedNdcCoords) {
736 const GLfloat *dstclip = VB->ClipPtr->data[edst];
Keith Whitwellfb2a95b2004-01-08 13:55:24 +0000737 if (dstclip[3] != 0.0) {
Karl Schultzc6c4cd82004-01-13 01:11:09 +0000738 const GLfloat w = 1.0f / dstclip[3];
Keith Whitwellfb2a95b2004-01-08 13:55:24 +0000739 GLfloat pos[4];
Keith Whitwell79073402004-01-05 09:43:42 +0000740
Keith Whitwellfb2a95b2004-01-08 13:55:24 +0000741 pos[0] = dstclip[0] * w;
742 pos[1] = dstclip[1] * w;
743 pos[2] = dstclip[2] * w;
744 pos[3] = w;
Keith Whitwell79073402004-01-05 09:43:42 +0000745
Keith Whitwellfb2a95b2004-01-08 13:55:24 +0000746 a[0].insert[4-1]( &a[0], vdst, pos );
747 }
Keith Whitwell79073402004-01-05 09:43:42 +0000748 }
749 else {
Keith Whitwell58822572004-01-05 15:24:53 +0000750 a[0].insert[4-1]( &a[0], vdst, VB->ClipPtr->data[edst] );
Keith Whitwell79073402004-01-05 09:43:42 +0000751 }
752
753
754 for (j = 1; j < attr_count; j++) {
Keith Whitwellfabb9732003-12-21 17:54:31 +0000755 GLfloat fin[4], fout[4], fdst[4];
Keith Whitwell79073402004-01-05 09:43:42 +0000756
757 a[j].extract( &a[j], fin, vin + a[j].vertoffset );
758 a[j].extract( &a[j], fout, vout + a[j].vertoffset );
Keith Whitwellfabb9732003-12-21 17:54:31 +0000759
760 INTERP_F( t, fdst[3], fout[3], fin[3] );
761 INTERP_F( t, fdst[2], fout[2], fin[2] );
762 INTERP_F( t, fdst[1], fout[1], fin[1] );
763 INTERP_F( t, fdst[0], fout[0], fin[0] );
764
Keith Whitwell58822572004-01-05 15:24:53 +0000765 a[j].insert[4-1]( &a[j], vdst + a[j].vertoffset, fdst );
Keith Whitwellfabb9732003-12-21 17:54:31 +0000766 }
767}
768
769
770/* Extract color attributes from one vertex and insert them into
771 * another. (Shortcircuit extract/insert with memcpy).
772 */
Keith Whitwell79073402004-01-05 09:43:42 +0000773static void generic_copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000774{
Keith Whitwell79073402004-01-05 09:43:42 +0000775 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
Keith Whitwell58822572004-01-05 15:24:53 +0000776 GLubyte *vsrc = vtx->vertex_buf + esrc * vtx->vertex_size;
777 GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size;
Keith Whitwell79073402004-01-05 09:43:42 +0000778 const struct tnl_clipspace_attr *a = vtx->attr;
Brian Paulfde4c532004-03-13 18:27:06 +0000779 const GLuint attr_count = vtx->attr_count;
780 GLuint j;
Keith Whitwellfabb9732003-12-21 17:54:31 +0000781
782 for (j = 0; j < attr_count; j++) {
Keith Whitwell79073402004-01-05 09:43:42 +0000783 if (a[j].attrib == VERT_ATTRIB_COLOR0 ||
784 a[j].attrib == VERT_ATTRIB_COLOR1) {
Keith Whitwellfabb9732003-12-21 17:54:31 +0000785
Brian Paul3663c0f2004-01-15 00:29:51 +0000786 _mesa_memcpy( vdst + a[j].vertoffset,
787 vsrc + a[j].vertoffset,
788 a[j].vertattrsize );
Keith Whitwell79073402004-01-05 09:43:42 +0000789 }
Keith Whitwellfabb9732003-12-21 17:54:31 +0000790 }
791}
792
Keith Whitwellfabb9732003-12-21 17:54:31 +0000793
Keith Whitwell79073402004-01-05 09:43:42 +0000794/* Helper functions for hardware which doesn't put back colors and/or
795 * edgeflags into vertices.
796 */
797static void generic_interp_extras( GLcontext *ctx,
798 GLfloat t,
799 GLuint dst, GLuint out, GLuint in,
800 GLboolean force_boundary )
801{
802 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
803
804 if (VB->ColorPtr[1]) {
805 assert(VB->ColorPtr[1]->stride == 4 * sizeof(GLfloat));
806
807 INTERP_4F( t,
808 VB->ColorPtr[1]->data[dst],
809 VB->ColorPtr[1]->data[out],
810 VB->ColorPtr[1]->data[in] );
811
812 if (VB->SecondaryColorPtr[1]) {
813 INTERP_3F( t,
814 VB->SecondaryColorPtr[1]->data[dst],
815 VB->SecondaryColorPtr[1]->data[out],
816 VB->SecondaryColorPtr[1]->data[in] );
Keith Whitwellfabb9732003-12-21 17:54:31 +0000817 }
818 }
Keith Whitwell58822572004-01-05 15:24:53 +0000819 else if (VB->IndexPtr[1]) {
820 VB->IndexPtr[1]->data[dst][0] = LINTERP( t,
821 VB->IndexPtr[1]->data[out][0],
822 VB->IndexPtr[1]->data[in][0] );
823 }
Keith Whitwellfabb9732003-12-21 17:54:31 +0000824
Keith Whitwell79073402004-01-05 09:43:42 +0000825 if (VB->EdgeFlag) {
826 VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary;
827 }
828
829 generic_interp(ctx, t, dst, out, in, force_boundary);
Keith Whitwellfabb9732003-12-21 17:54:31 +0000830}
831
Keith Whitwell79073402004-01-05 09:43:42 +0000832static void generic_copy_pv_extras( GLcontext *ctx,
833 GLuint dst, GLuint src )
834{
835 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
836
837 if (VB->ColorPtr[1]) {
838 COPY_4FV( VB->ColorPtr[1]->data[dst],
839 VB->ColorPtr[1]->data[src] );
840
841 if (VB->SecondaryColorPtr[1]) {
842 COPY_4FV( VB->SecondaryColorPtr[1]->data[dst],
843 VB->SecondaryColorPtr[1]->data[src] );
844 }
845 }
Keith Whitwell58822572004-01-05 15:24:53 +0000846 else if (VB->IndexPtr[1]) {
847 VB->IndexPtr[1]->data[dst][0] = VB->IndexPtr[1]->data[src][0];
848 }
Keith Whitwell79073402004-01-05 09:43:42 +0000849
Keith Whitwellef167c62004-01-26 21:34:28 +0000850 generic_copy_pv(ctx, dst, src);
Keith Whitwell79073402004-01-05 09:43:42 +0000851}
Keith Whitwellfabb9732003-12-21 17:54:31 +0000852
853
854
855
Keith Whitwellfabb9732003-12-21 17:54:31 +0000856/***********************************************************************
857 * Build codegen functions or return generic ones:
858 */
859
860
Keith Whitwell009aa3e2004-06-30 11:48:21 +0000861static void do_emit( GLcontext *ctx, GLuint start, GLuint end,
862 void *dest)
Keith Whitwellfabb9732003-12-21 17:54:31 +0000863{
Keith Whitwell009aa3e2004-06-30 11:48:21 +0000864 TNLcontext *tnl = TNL_CONTEXT(ctx);
865 struct vertex_buffer *VB = &tnl->vb;
Keith Whitwell79073402004-01-05 09:43:42 +0000866 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
Keith Whitwell009aa3e2004-06-30 11:48:21 +0000867 struct tnl_clipspace_attr *a = vtx->attr;
868 const GLuint count = vtx->attr_count;
869 GLuint j;
870
871 for (j = 0; j < count; j++) {
872 GLvector4f *vptr = VB->AttribPtr[a[j].attrib];
873 a[j].inputstride = vptr->stride;
874 a[j].inputptr = ((GLubyte *)vptr->data) + start * vptr->stride;
875 a[j].emit = a[j].insert[vptr->size - 1];
876 }
877
878 vtx->emit = 0;
879
880 if (0)
881 vtx->emit = _tnl_codegen_emit(ctx);
882
883 if (!vtx->emit)
884 vtx->emit = generic_emit;
885
Keith Whitwell79073402004-01-05 09:43:42 +0000886 vtx->emit( ctx, start, end, dest );
Keith Whitwellfabb9732003-12-21 17:54:31 +0000887}
888
889
Keith Whitwell009aa3e2004-06-30 11:48:21 +0000890
Keith Whitwellfabb9732003-12-21 17:54:31 +0000891static void choose_interp_func( GLcontext *ctx,
892 GLfloat t,
893 GLuint edst, GLuint eout, GLuint ein,
894 GLboolean force_boundary )
895{
Keith Whitwell79073402004-01-05 09:43:42 +0000896 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
897
898 if (vtx->need_extras &&
899 (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
900 vtx->interp = generic_interp_extras;
901 } else {
902 vtx->interp = generic_interp;
903 }
904
905 vtx->interp( ctx, t, edst, eout, ein, force_boundary );
Keith Whitwellfabb9732003-12-21 17:54:31 +0000906}
907
908
Keith Whitwell79073402004-01-05 09:43:42 +0000909static void choose_copy_pv_func( GLcontext *ctx, GLuint edst, GLuint esrc )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000910{
Keith Whitwell79073402004-01-05 09:43:42 +0000911 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
912
913 if (vtx->need_extras &&
914 (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
915 vtx->copy_pv = generic_copy_pv_extras;
916 } else {
917 vtx->copy_pv = generic_copy_pv;
918 }
919
920 vtx->copy_pv( ctx, edst, esrc );
Keith Whitwellfabb9732003-12-21 17:54:31 +0000921}
922
923
924/***********************************************************************
925 * Public entrypoints, mostly dispatch to the above:
926 */
927
Keith Whitwellfabb9732003-12-21 17:54:31 +0000928
929/* Interpolate between two vertices to produce a third:
930 */
931void _tnl_interp( GLcontext *ctx,
932 GLfloat t,
933 GLuint edst, GLuint eout, GLuint ein,
934 GLboolean force_boundary )
935{
Keith Whitwell79073402004-01-05 09:43:42 +0000936 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
937 vtx->interp( ctx, t, edst, eout, ein, force_boundary );
Keith Whitwellfabb9732003-12-21 17:54:31 +0000938}
939
940/* Copy colors from one vertex to another:
941 */
Keith Whitwell79073402004-01-05 09:43:42 +0000942void _tnl_copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000943{
Keith Whitwell79073402004-01-05 09:43:42 +0000944 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
945 vtx->copy_pv( ctx, edst, esrc );
Keith Whitwellfabb9732003-12-21 17:54:31 +0000946}
947
948
949/* Extract a named attribute from a hardware vertex. Will have to
950 * reverse any viewport transformation, swizzling or other conversions
951 * which may have been applied:
952 */
Keith Whitwell79073402004-01-05 09:43:42 +0000953void _tnl_get_attr( GLcontext *ctx, const void *vin,
954 GLenum attr, GLfloat *dest )
Keith Whitwellfabb9732003-12-21 17:54:31 +0000955{
Keith Whitwell79073402004-01-05 09:43:42 +0000956 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
957 const struct tnl_clipspace_attr *a = vtx->attr;
Brian Paulfde4c532004-03-13 18:27:06 +0000958 const GLuint attr_count = vtx->attr_count;
959 GLuint j;
Keith Whitwell79073402004-01-05 09:43:42 +0000960
961 for (j = 0; j < attr_count; j++) {
Brian Paulbdd15b52004-05-04 15:11:06 +0000962 if (a[j].attrib == attr) {
Keith Whitwell44d4a8f2004-01-06 00:18:03 +0000963 a[j].extract( &a[j], dest, (GLubyte *)vin + a[j].vertoffset );
Keith Whitwell79073402004-01-05 09:43:42 +0000964 return;
965 }
966 }
967
Keith Whitwell47736342004-02-16 15:15:24 +0000968 /* Else return the value from ctx->Current -- dangerous???
Keith Whitwell79073402004-01-05 09:43:42 +0000969 */
Brian Paul3663c0f2004-01-15 00:29:51 +0000970 _mesa_memcpy( dest, ctx->Current.Attrib[attr], 4*sizeof(GLfloat));
Keith Whitwell79073402004-01-05 09:43:42 +0000971}
972
Keith Whitwell47736342004-02-16 15:15:24 +0000973
974/* Complementary operation to the above.
975 */
976void _tnl_set_attr( GLcontext *ctx, void *vout,
977 GLenum attr, const GLfloat *src )
978{
979 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
980 const struct tnl_clipspace_attr *a = vtx->attr;
Brian Paulfde4c532004-03-13 18:27:06 +0000981 const GLuint attr_count = vtx->attr_count;
982 GLuint j;
Keith Whitwell47736342004-02-16 15:15:24 +0000983
984 for (j = 0; j < attr_count; j++) {
Brian Paulbdd15b52004-05-04 15:11:06 +0000985 if (a[j].attrib == attr) {
Keith Whitwell47736342004-02-16 15:15:24 +0000986 a[j].insert[4-1]( &a[j], (GLubyte *)vout + a[j].vertoffset, src );
987 return;
988 }
989 }
990}
991
992
Keith Whitwell79073402004-01-05 09:43:42 +0000993void *_tnl_get_vertex( GLcontext *ctx, GLuint nr )
994{
995 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
996
997 return vtx->vertex_buf + nr * vtx->vertex_size;
998}
999
1000void _tnl_invalidate_vertex_state( GLcontext *ctx, GLuint new_state )
1001{
1002 if (new_state & (_DD_NEW_TRI_LIGHT_TWOSIDE|_DD_NEW_TRI_UNFILLED) ) {
1003 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1004 vtx->new_inputs = ~0;
1005 vtx->interp = choose_interp_func;
1006 vtx->copy_pv = choose_copy_pv_func;
1007 }
Keith Whitwellfabb9732003-12-21 17:54:31 +00001008}
1009
1010
Keith Whitwell79073402004-01-05 09:43:42 +00001011GLuint _tnl_install_attrs( GLcontext *ctx, const struct tnl_attr_map *map,
Keith Whitwell58822572004-01-05 15:24:53 +00001012 GLuint nr, const GLfloat *vp,
1013 GLuint unpacked_size )
Keith Whitwellfabb9732003-12-21 17:54:31 +00001014{
Keith Whitwell79073402004-01-05 09:43:42 +00001015 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
Brian Paulfde4c532004-03-13 18:27:06 +00001016 GLuint offset = 0;
Keith Whitwell4d36f332004-01-21 15:31:46 +00001017 GLuint i, j;
Keith Whitwellfabb9732003-12-21 17:54:31 +00001018
Keith Whitwell79073402004-01-05 09:43:42 +00001019 assert(nr < _TNL_ATTRIB_MAX);
1020 assert(nr == 0 || map[0].attrib == VERT_ATTRIB_POS);
Keith Whitwellfabb9732003-12-21 17:54:31 +00001021
Keith Whitwell009aa3e2004-06-30 11:48:21 +00001022 vtx->emit = 0;
Keith Whitwell79073402004-01-05 09:43:42 +00001023 vtx->interp = choose_interp_func;
1024 vtx->copy_pv = choose_copy_pv_func;
1025 vtx->new_inputs = ~0;
Keith Whitwellfabb9732003-12-21 17:54:31 +00001026
Keith Whitwell4d36f332004-01-21 15:31:46 +00001027 for (j = 0, i = 0; i < nr; i++) {
Brian Paulfde4c532004-03-13 18:27:06 +00001028 const GLuint format = map[i].format;
Keith Whitwell4d36f332004-01-21 15:31:46 +00001029 if (format == EMIT_PAD) {
Keith Whitwell009aa3e2004-06-30 11:48:21 +00001030 fprintf(stderr, "%d: pad %d, offset %d\n", i,
1031 map[i].offset, offset);
Keith Whitwell16f54212004-01-05 15:55:01 +00001032
Keith Whitwell009aa3e2004-06-30 11:48:21 +00001033 offset += map[i].offset;
Keith Whitwell16f54212004-01-05 15:55:01 +00001034
Keith Whitwell4d36f332004-01-21 15:31:46 +00001035 }
1036 else {
1037 vtx->attr[j].attrib = map[i].attrib;
Keith Whitwell009aa3e2004-06-30 11:48:21 +00001038 vtx->attr[j].format = format;
Keith Whitwell4d36f332004-01-21 15:31:46 +00001039 vtx->attr[j].vp = vp;
1040 vtx->attr[j].insert = format_info[format].insert;
1041 vtx->attr[j].extract = format_info[format].extract;
1042 vtx->attr[j].vertattrsize = format_info[format].attrsize;
Keith Whitwell44d4a8f2004-01-06 00:18:03 +00001043
Keith Whitwell4d36f332004-01-21 15:31:46 +00001044 if (unpacked_size)
1045 vtx->attr[j].vertoffset = map[i].offset;
1046 else
1047 vtx->attr[j].vertoffset = offset;
1048
Keith Whitwell009aa3e2004-06-30 11:48:21 +00001049 fprintf(stderr, "%d: %s, vp %p, offset %d\n", i,
1050 format_info[format].name, (void *)vp,
1051 vtx->attr[j].vertoffset);
Keith Whitwell4d36f332004-01-21 15:31:46 +00001052
1053 offset += format_info[format].attrsize;
1054 j++;
1055 }
Keith Whitwellfabb9732003-12-21 17:54:31 +00001056 }
Keith Whitwell79073402004-01-05 09:43:42 +00001057
Keith Whitwell4d36f332004-01-21 15:31:46 +00001058 vtx->attr_count = j;
1059
Keith Whitwell58822572004-01-05 15:24:53 +00001060 if (unpacked_size)
1061 vtx->vertex_size = unpacked_size;
1062 else
1063 vtx->vertex_size = offset;
Keith Whitwell79073402004-01-05 09:43:42 +00001064
Keith Whitwell58822572004-01-05 15:24:53 +00001065 assert(vtx->vertex_size <= vtx->max_vertex_size);
1066
Keith Whitwell79073402004-01-05 09:43:42 +00001067 return vtx->vertex_size;
Keith Whitwellfabb9732003-12-21 17:54:31 +00001068}
1069
1070
1071
Keith Whitwell79073402004-01-05 09:43:42 +00001072void _tnl_invalidate_vertices( GLcontext *ctx, GLuint newinputs )
Keith Whitwellfabb9732003-12-21 17:54:31 +00001073{
Keith Whitwell79073402004-01-05 09:43:42 +00001074 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1075 vtx->new_inputs |= newinputs;
Keith Whitwellfabb9732003-12-21 17:54:31 +00001076}
1077
1078
Keith Whitwell79073402004-01-05 09:43:42 +00001079void _tnl_build_vertices( GLcontext *ctx,
Keith Whitwell8d97ad12004-01-19 23:29:40 +00001080 GLuint start,
1081 GLuint end,
1082 GLuint newinputs )
Keith Whitwellfabb9732003-12-21 17:54:31 +00001083{
Keith Whitwell79073402004-01-05 09:43:42 +00001084 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
Brian Paulfde4c532004-03-13 18:27:06 +00001085 const GLuint stride = vtx->vertex_size;
1086 GLubyte *vDest = ((GLubyte *)vtx->vertex_buf + (start*stride));
Keith Whitwellfabb9732003-12-21 17:54:31 +00001087
Keith Whitwell79073402004-01-05 09:43:42 +00001088 newinputs |= vtx->new_inputs;
1089 vtx->new_inputs = 0;
Keith Whitwellfabb9732003-12-21 17:54:31 +00001090
Keith Whitwell009aa3e2004-06-30 11:48:21 +00001091 if (newinputs)
1092 do_emit( ctx, start, end, vDest );
Keith Whitwellfabb9732003-12-21 17:54:31 +00001093}
1094
Keith Whitwell79073402004-01-05 09:43:42 +00001095
1096void *_tnl_emit_vertices_to_buffer( GLcontext *ctx,
Keith Whitwell8d97ad12004-01-19 23:29:40 +00001097 GLuint start,
1098 GLuint end,
1099 void *dest )
Keith Whitwellfabb9732003-12-21 17:54:31 +00001100{
Keith Whitwell79073402004-01-05 09:43:42 +00001101 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
Keith Whitwell009aa3e2004-06-30 11:48:21 +00001102 do_emit( ctx, start, end, dest );
Keith Whitwell8d97ad12004-01-19 23:29:40 +00001103 return (void *)((GLubyte *)dest + vtx->vertex_size * (end - start));
Keith Whitwellfabb9732003-12-21 17:54:31 +00001104}
1105
Keith Whitwell79073402004-01-05 09:43:42 +00001106
1107void _tnl_init_vertices( GLcontext *ctx,
1108 GLuint vb_size,
1109 GLuint max_vertex_size )
1110{
1111 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1112
Keith Whitwell58822572004-01-05 15:24:53 +00001113 _tnl_install_attrs( ctx, 0, 0, 0, 0 );
Keith Whitwell79073402004-01-05 09:43:42 +00001114
1115 vtx->need_extras = GL_TRUE;
Keith Whitwell58822572004-01-05 15:24:53 +00001116 if (max_vertex_size > vtx->max_vertex_size) {
1117 _tnl_free_vertices( ctx );
1118 vtx->max_vertex_size = max_vertex_size;
Brian Paulcb7c6892004-01-26 16:16:16 +00001119 vtx->vertex_buf = (GLubyte *)ALIGN_CALLOC(vb_size * max_vertex_size, 32 );
Keith Whitwell58822572004-01-05 15:24:53 +00001120 }
Keith Whitwell009aa3e2004-06-30 11:48:21 +00001121
1122 _tnl_init_c_codegen( &vtx->codegen );
Keith Whitwell79073402004-01-05 09:43:42 +00001123}
1124
1125
1126void _tnl_free_vertices( GLcontext *ctx )
1127{
1128 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
1129 if (vtx->vertex_buf) {
1130 ALIGN_FREE(vtx->vertex_buf);
1131 vtx->vertex_buf = 0;
1132 }
1133}