added GL_EXT_stencil_two_side and GL_NV_fence
[mesa.git] / src / mesa / swrast_setup / ss_vb.c
1 /* $Id: ss_vb.c,v 1.20 2002/06/29 19:48:17 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 4.1
6 *
7 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 * Authors:
27 * Keith Whitwell <keithw@valinux.com>
28 */
29
30 #include "glheader.h"
31 #include "colormac.h"
32 #include "context.h"
33 #include "macros.h"
34 #include "mem.h"
35
36 #include "swrast/swrast.h"
37 #include "tnl/t_context.h"
38 #include "math/m_vector.h"
39 #include "math/m_translate.h"
40
41 #include "ss_context.h"
42 #include "ss_vb.h"
43
44 static void do_import( struct vertex_buffer *VB,
45 struct gl_client_array *to,
46 struct gl_client_array *from )
47 {
48 GLuint count = VB->Count;
49
50 if (!to->Ptr) {
51 to->Ptr = ALIGN_MALLOC( VB->Size * 4 * sizeof(GLchan), 32 );
52 to->Type = CHAN_TYPE;
53 }
54
55 /* No need to transform the same value 3000 times.
56 */
57 if (!from->StrideB) {
58 to->StrideB = 0;
59 count = 1;
60 }
61 else
62 to->StrideB = 4 * sizeof(GLchan);
63
64 _math_trans_4chan( (GLchan (*)[4]) to->Ptr,
65 from->Ptr,
66 from->StrideB,
67 from->Type,
68 from->Size,
69 0,
70 count);
71 }
72
73 static void import_float_colors( GLcontext *ctx )
74 {
75 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
76 struct gl_client_array *to = &SWSETUP_CONTEXT(ctx)->ChanColor;
77 do_import( VB, to, VB->ColorPtr[0] );
78 VB->ColorPtr[0] = to;
79 }
80
81 static void import_float_spec_colors( GLcontext *ctx )
82 {
83 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
84 struct gl_client_array *to = &SWSETUP_CONTEXT(ctx)->ChanSecondaryColor;
85 do_import( VB, to, VB->SecondaryColorPtr[0] );
86 VB->SecondaryColorPtr[0] = to;
87 }
88
89
90 /* Provides a RasterSetup function which prebuilds vertices for the
91 * software rasterizer. This is required for the triangle functions
92 * in this module, but not the rest of the swrast module.
93 */
94
95
96 #define COLOR 0x1
97 #define INDEX 0x2
98 #define TEX0 0x4
99 #define MULTITEX 0x8
100 #define SPEC 0x10
101 #define FOG 0x20
102 #define POINT 0x40
103 #define MAX_SETUPFUNC 0x80
104
105 static setup_func setup_tab[MAX_SETUPFUNC];
106 static interp_func interp_tab[MAX_SETUPFUNC];
107 static copy_pv_func copy_pv_tab[MAX_SETUPFUNC];
108
109
110 #define IND (0)
111 #define TAG(x) x##_none
112 #include "ss_vbtmp.h"
113
114 #define IND (COLOR)
115 #define TAG(x) x##_color
116 #include "ss_vbtmp.h"
117
118 #define IND (COLOR|SPEC)
119 #define TAG(x) x##_color_spec
120 #include "ss_vbtmp.h"
121
122 #define IND (COLOR|FOG)
123 #define TAG(x) x##_color_fog
124 #include "ss_vbtmp.h"
125
126 #define IND (COLOR|SPEC|FOG)
127 #define TAG(x) x##_color_spec_fog
128 #include "ss_vbtmp.h"
129
130 #define IND (COLOR|TEX0)
131 #define TAG(x) x##_color_tex0
132 #include "ss_vbtmp.h"
133
134 #define IND (COLOR|TEX0|SPEC)
135 #define TAG(x) x##_color_tex0_spec
136 #include "ss_vbtmp.h"
137
138 #define IND (COLOR|TEX0|FOG)
139 #define TAG(x) x##_color_tex0_fog
140 #include "ss_vbtmp.h"
141
142 #define IND (COLOR|TEX0|SPEC|FOG)
143 #define TAG(x) x##_color_tex0_spec_fog
144 #include "ss_vbtmp.h"
145
146 #define IND (COLOR|MULTITEX)
147 #define TAG(x) x##_color_multitex
148 #include "ss_vbtmp.h"
149
150 #define IND (COLOR|MULTITEX|SPEC)
151 #define TAG(x) x##_color_multitex_spec
152 #include "ss_vbtmp.h"
153
154 #define IND (COLOR|MULTITEX|FOG)
155 #define TAG(x) x##_color_multitex_fog
156 #include "ss_vbtmp.h"
157
158 #define IND (COLOR|MULTITEX|SPEC|FOG)
159 #define TAG(x) x##_color_multitex_spec_fog
160 #include "ss_vbtmp.h"
161
162 #define IND (COLOR|POINT)
163 #define TAG(x) x##_color_point
164 #include "ss_vbtmp.h"
165
166 #define IND (COLOR|SPEC|POINT)
167 #define TAG(x) x##_color_spec_point
168 #include "ss_vbtmp.h"
169
170 #define IND (COLOR|FOG|POINT)
171 #define TAG(x) x##_color_fog_point
172 #include "ss_vbtmp.h"
173
174 #define IND (COLOR|SPEC|FOG|POINT)
175 #define TAG(x) x##_color_spec_fog_point
176 #include "ss_vbtmp.h"
177
178 #define IND (COLOR|TEX0|POINT)
179 #define TAG(x) x##_color_tex0_point
180 #include "ss_vbtmp.h"
181
182 #define IND (COLOR|TEX0|SPEC|POINT)
183 #define TAG(x) x##_color_tex0_spec_point
184 #include "ss_vbtmp.h"
185
186 #define IND (COLOR|TEX0|FOG|POINT)
187 #define TAG(x) x##_color_tex0_fog_point
188 #include "ss_vbtmp.h"
189
190 #define IND (COLOR|TEX0|SPEC|FOG|POINT)
191 #define TAG(x) x##_color_tex0_spec_fog_point
192 #include "ss_vbtmp.h"
193
194 #define IND (COLOR|MULTITEX|POINT)
195 #define TAG(x) x##_color_multitex_point
196 #include "ss_vbtmp.h"
197
198 #define IND (COLOR|MULTITEX|SPEC|POINT)
199 #define TAG(x) x##_color_multitex_spec_point
200 #include "ss_vbtmp.h"
201
202 #define IND (COLOR|MULTITEX|FOG|POINT)
203 #define TAG(x) x##_color_multitex_fog_point
204 #include "ss_vbtmp.h"
205
206 #define IND (COLOR|MULTITEX|SPEC|FOG|POINT)
207 #define TAG(x) x##_color_multitex_spec_fog_point
208 #include "ss_vbtmp.h"
209
210 #define IND (INDEX)
211 #define TAG(x) x##_index
212 #include "ss_vbtmp.h"
213
214 #define IND (INDEX|FOG)
215 #define TAG(x) x##_index_fog
216 #include "ss_vbtmp.h"
217
218 #define IND (INDEX|POINT)
219 #define TAG(x) x##_index_point
220 #include "ss_vbtmp.h"
221
222 #define IND (INDEX|FOG|POINT)
223 #define TAG(x) x##_index_fog_point
224 #include "ss_vbtmp.h"
225
226
227 /***********************************************************************
228 * Additional setup and interp for back color and edgeflag.
229 ***********************************************************************/
230
231 #define GET_COLOR(ptr, idx) (((GLchan (*)[4])((ptr)->Ptr))[idx])
232
233 static void interp_extras( GLcontext *ctx,
234 GLfloat t,
235 GLuint dst, GLuint out, GLuint in,
236 GLboolean force_boundary )
237 {
238 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
239
240 if (VB->ColorPtr[1]) {
241 INTERP_4CHAN( t,
242 GET_COLOR(VB->ColorPtr[1], dst),
243 GET_COLOR(VB->ColorPtr[1], out),
244 GET_COLOR(VB->ColorPtr[1], in) );
245
246 if (VB->SecondaryColorPtr[1]) {
247 INTERP_3CHAN( t,
248 GET_COLOR(VB->SecondaryColorPtr[1], dst),
249 GET_COLOR(VB->SecondaryColorPtr[1], out),
250 GET_COLOR(VB->SecondaryColorPtr[1], in) );
251 }
252 }
253 else if (VB->IndexPtr[1]) {
254 VB->IndexPtr[1]->data[dst] = (GLuint) (GLint)
255 LINTERP( t,
256 (GLfloat) VB->IndexPtr[1]->data[out],
257 (GLfloat) VB->IndexPtr[1]->data[in] );
258 }
259
260 if (VB->EdgeFlag) {
261 VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary;
262 }
263
264 interp_tab[SWSETUP_CONTEXT(ctx)->SetupIndex](ctx, t, dst, out, in,
265 force_boundary);
266 }
267
268 static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src )
269 {
270 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
271
272 if (VB->ColorPtr[1]) {
273 COPY_CHAN4( GET_COLOR(VB->ColorPtr[1], dst),
274 GET_COLOR(VB->ColorPtr[1], src) );
275
276 if (VB->SecondaryColorPtr[1]) {
277 COPY_3V( GET_COLOR(VB->SecondaryColorPtr[1], dst),
278 GET_COLOR(VB->SecondaryColorPtr[1], src) );
279 }
280 }
281 else if (VB->IndexPtr[1]) {
282 VB->IndexPtr[1]->data[dst] = VB->IndexPtr[1]->data[src];
283 }
284
285 copy_pv_tab[SWSETUP_CONTEXT(ctx)->SetupIndex](ctx, dst, src);
286 }
287
288
289
290
291 /***********************************************************************
292 * Initialization
293 ***********************************************************************/
294
295 static void
296 emit_invalid( GLcontext *ctx, GLuint start, GLuint end, GLuint newinputs )
297 {
298 _mesa_debug(ctx, "swrast_setup: invalid setup function\n");
299 (void) (ctx && start && end && newinputs);
300 }
301
302
303 static void
304 interp_invalid( GLcontext *ctx, GLfloat t,
305 GLuint edst, GLuint eout, GLuint ein,
306 GLboolean force_boundary )
307 {
308 _mesa_debug(ctx, "swrast_setup: invalid interp function\n");
309 (void) (ctx && t && edst && eout && ein && force_boundary);
310 }
311
312
313 static void
314 copy_pv_invalid( GLcontext *ctx, GLuint edst, GLuint esrc )
315 {
316 _mesa_debug(ctx, "swrast_setup: invalid copy_pv function\n");
317 (void) (ctx && edst && esrc );
318 }
319
320
321 static void init_standard( void )
322 {
323 GLuint i;
324
325 for (i = 0 ; i < Elements(setup_tab) ; i++) {
326 setup_tab[i] = emit_invalid;
327 interp_tab[i] = interp_invalid;
328 copy_pv_tab[i] = copy_pv_invalid;
329 }
330
331 init_none();
332 init_color();
333 init_color_spec();
334 init_color_fog();
335 init_color_spec_fog();
336 init_color_tex0();
337 init_color_tex0_spec();
338 init_color_tex0_fog();
339 init_color_tex0_spec_fog();
340 init_color_multitex();
341 init_color_multitex_spec();
342 init_color_multitex_fog();
343 init_color_multitex_spec_fog();
344 init_color_point();
345 init_color_spec_point();
346 init_color_fog_point();
347 init_color_spec_fog_point();
348 init_color_tex0_point();
349 init_color_tex0_spec_point();
350 init_color_tex0_fog_point();
351 init_color_tex0_spec_fog_point();
352 init_color_multitex_point();
353 init_color_multitex_spec_point();
354 init_color_multitex_fog_point();
355 init_color_multitex_spec_fog_point();
356 init_index();
357 init_index_fog();
358 init_index_point();
359 init_index_fog_point();
360 }
361
362
363 /* debug only */
364 #if 0
365 static void
366 printSetupFlags(const GLcontext *ctx, char *msg, GLuint flags )
367 {
368 _mesa_debug(ctx, "%s(%x): %s%s%s%s%s%s%s\n",
369 msg,
370 (int) flags,
371 (flags & COLOR) ? "color, " : "",
372 (flags & INDEX) ? "index, " : "",
373 (flags & TEX0) ? "tex0, " : "",
374 (flags & MULTITEX) ? "multitex, " : "",
375 (flags & SPEC) ? "spec, " : "",
376 (flags & FOG) ? "fog, " : "",
377 (flags & POINT) ? "point, " : "");
378 }
379 #endif
380
381 void
382 _swsetup_choose_rastersetup_func(GLcontext *ctx)
383 {
384 SScontext *swsetup = SWSETUP_CONTEXT(ctx);
385 TNLcontext *tnl = TNL_CONTEXT(ctx);
386 int funcindex = 0;
387
388 if (ctx->RenderMode == GL_RENDER) {
389 if (ctx->Visual.rgbMode) {
390 funcindex = COLOR;
391
392 if (ctx->Texture._EnabledUnits > 1)
393 funcindex |= MULTITEX; /* a unit above unit[0] is enabled */
394 else if (ctx->Texture._EnabledUnits == 1)
395 funcindex |= TEX0; /* only unit 0 is enabled */
396
397 if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
398 funcindex |= SPEC;
399 }
400 else {
401 funcindex = INDEX;
402 }
403
404 if (ctx->Point._Attenuated ||
405 (ctx->VertexProgram.Enabled && ctx->VertexProgram.PointSizeEnabled))
406 funcindex |= POINT;
407
408 if (ctx->Fog.Enabled)
409 funcindex |= FOG;
410 }
411 else if (ctx->RenderMode == GL_FEEDBACK) {
412 if (ctx->Visual.rgbMode)
413 funcindex = (COLOR | TEX0); /* is feedback color subject to fogging? */
414 else
415 funcindex = INDEX;
416 }
417 else
418 funcindex = 0;
419
420 swsetup->SetupIndex = funcindex;
421 tnl->Driver.Render.BuildVertices = setup_tab[funcindex];
422
423 if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
424 tnl->Driver.Render.Interp = interp_extras;
425 tnl->Driver.Render.CopyPV = copy_pv_extras;
426 }
427 else {
428 tnl->Driver.Render.Interp = interp_tab[funcindex];
429 tnl->Driver.Render.CopyPV = copy_pv_tab[funcindex];
430 }
431
432 ASSERT(tnl->Driver.Render.BuildVertices);
433 ASSERT(tnl->Driver.Render.BuildVertices != emit_invalid);
434 }
435
436
437 void
438 _swsetup_vb_init( GLcontext *ctx )
439 {
440 (void) ctx;
441 init_standard();
442 /*
443 printSetupFlags(ctx);
444 */
445 }
446