1 /* $Id: ss_vb.c,v 1.20 2002/06/29 19:48:17 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
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:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
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.
27 * Keith Whitwell <keithw@valinux.com>
36 #include "swrast/swrast.h"
37 #include "tnl/t_context.h"
38 #include "math/m_vector.h"
39 #include "math/m_translate.h"
41 #include "ss_context.h"
44 static void do_import( struct vertex_buffer
*VB
,
45 struct gl_client_array
*to
,
46 struct gl_client_array
*from
)
48 GLuint count
= VB
->Count
;
51 to
->Ptr
= ALIGN_MALLOC( VB
->Size
* 4 * sizeof(GLchan
), 32 );
55 /* No need to transform the same value 3000 times.
62 to
->StrideB
= 4 * sizeof(GLchan
);
64 _math_trans_4chan( (GLchan (*)[4]) to
->Ptr
,
73 static void import_float_colors( GLcontext
*ctx
)
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] );
81 static void import_float_spec_colors( GLcontext
*ctx
)
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
;
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.
103 #define MAX_SETUPFUNC 0x80
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
];
111 #define TAG(x) x##_none
112 #include "ss_vbtmp.h"
115 #define TAG(x) x##_color
116 #include "ss_vbtmp.h"
118 #define IND (COLOR|SPEC)
119 #define TAG(x) x##_color_spec
120 #include "ss_vbtmp.h"
122 #define IND (COLOR|FOG)
123 #define TAG(x) x##_color_fog
124 #include "ss_vbtmp.h"
126 #define IND (COLOR|SPEC|FOG)
127 #define TAG(x) x##_color_spec_fog
128 #include "ss_vbtmp.h"
130 #define IND (COLOR|TEX0)
131 #define TAG(x) x##_color_tex0
132 #include "ss_vbtmp.h"
134 #define IND (COLOR|TEX0|SPEC)
135 #define TAG(x) x##_color_tex0_spec
136 #include "ss_vbtmp.h"
138 #define IND (COLOR|TEX0|FOG)
139 #define TAG(x) x##_color_tex0_fog
140 #include "ss_vbtmp.h"
142 #define IND (COLOR|TEX0|SPEC|FOG)
143 #define TAG(x) x##_color_tex0_spec_fog
144 #include "ss_vbtmp.h"
146 #define IND (COLOR|MULTITEX)
147 #define TAG(x) x##_color_multitex
148 #include "ss_vbtmp.h"
150 #define IND (COLOR|MULTITEX|SPEC)
151 #define TAG(x) x##_color_multitex_spec
152 #include "ss_vbtmp.h"
154 #define IND (COLOR|MULTITEX|FOG)
155 #define TAG(x) x##_color_multitex_fog
156 #include "ss_vbtmp.h"
158 #define IND (COLOR|MULTITEX|SPEC|FOG)
159 #define TAG(x) x##_color_multitex_spec_fog
160 #include "ss_vbtmp.h"
162 #define IND (COLOR|POINT)
163 #define TAG(x) x##_color_point
164 #include "ss_vbtmp.h"
166 #define IND (COLOR|SPEC|POINT)
167 #define TAG(x) x##_color_spec_point
168 #include "ss_vbtmp.h"
170 #define IND (COLOR|FOG|POINT)
171 #define TAG(x) x##_color_fog_point
172 #include "ss_vbtmp.h"
174 #define IND (COLOR|SPEC|FOG|POINT)
175 #define TAG(x) x##_color_spec_fog_point
176 #include "ss_vbtmp.h"
178 #define IND (COLOR|TEX0|POINT)
179 #define TAG(x) x##_color_tex0_point
180 #include "ss_vbtmp.h"
182 #define IND (COLOR|TEX0|SPEC|POINT)
183 #define TAG(x) x##_color_tex0_spec_point
184 #include "ss_vbtmp.h"
186 #define IND (COLOR|TEX0|FOG|POINT)
187 #define TAG(x) x##_color_tex0_fog_point
188 #include "ss_vbtmp.h"
190 #define IND (COLOR|TEX0|SPEC|FOG|POINT)
191 #define TAG(x) x##_color_tex0_spec_fog_point
192 #include "ss_vbtmp.h"
194 #define IND (COLOR|MULTITEX|POINT)
195 #define TAG(x) x##_color_multitex_point
196 #include "ss_vbtmp.h"
198 #define IND (COLOR|MULTITEX|SPEC|POINT)
199 #define TAG(x) x##_color_multitex_spec_point
200 #include "ss_vbtmp.h"
202 #define IND (COLOR|MULTITEX|FOG|POINT)
203 #define TAG(x) x##_color_multitex_fog_point
204 #include "ss_vbtmp.h"
206 #define IND (COLOR|MULTITEX|SPEC|FOG|POINT)
207 #define TAG(x) x##_color_multitex_spec_fog_point
208 #include "ss_vbtmp.h"
211 #define TAG(x) x##_index
212 #include "ss_vbtmp.h"
214 #define IND (INDEX|FOG)
215 #define TAG(x) x##_index_fog
216 #include "ss_vbtmp.h"
218 #define IND (INDEX|POINT)
219 #define TAG(x) x##_index_point
220 #include "ss_vbtmp.h"
222 #define IND (INDEX|FOG|POINT)
223 #define TAG(x) x##_index_fog_point
224 #include "ss_vbtmp.h"
227 /***********************************************************************
228 * Additional setup and interp for back color and edgeflag.
229 ***********************************************************************/
231 #define GET_COLOR(ptr, idx) (((GLchan (*)[4])((ptr)->Ptr))[idx])
233 static void interp_extras( GLcontext
*ctx
,
235 GLuint dst
, GLuint out
, GLuint in
,
236 GLboolean force_boundary
)
238 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
240 if (VB
->ColorPtr
[1]) {
242 GET_COLOR(VB
->ColorPtr
[1], dst
),
243 GET_COLOR(VB
->ColorPtr
[1], out
),
244 GET_COLOR(VB
->ColorPtr
[1], in
) );
246 if (VB
->SecondaryColorPtr
[1]) {
248 GET_COLOR(VB
->SecondaryColorPtr
[1], dst
),
249 GET_COLOR(VB
->SecondaryColorPtr
[1], out
),
250 GET_COLOR(VB
->SecondaryColorPtr
[1], in
) );
253 else if (VB
->IndexPtr
[1]) {
254 VB
->IndexPtr
[1]->data
[dst
] = (GLuint
) (GLint
)
256 (GLfloat
) VB
->IndexPtr
[1]->data
[out
],
257 (GLfloat
) VB
->IndexPtr
[1]->data
[in
] );
261 VB
->EdgeFlag
[dst
] = VB
->EdgeFlag
[out
] || force_boundary
;
264 interp_tab
[SWSETUP_CONTEXT(ctx
)->SetupIndex
](ctx
, t
, dst
, out
, in
,
268 static void copy_pv_extras( GLcontext
*ctx
, GLuint dst
, GLuint src
)
270 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
272 if (VB
->ColorPtr
[1]) {
273 COPY_CHAN4( GET_COLOR(VB
->ColorPtr
[1], dst
),
274 GET_COLOR(VB
->ColorPtr
[1], src
) );
276 if (VB
->SecondaryColorPtr
[1]) {
277 COPY_3V( GET_COLOR(VB
->SecondaryColorPtr
[1], dst
),
278 GET_COLOR(VB
->SecondaryColorPtr
[1], src
) );
281 else if (VB
->IndexPtr
[1]) {
282 VB
->IndexPtr
[1]->data
[dst
] = VB
->IndexPtr
[1]->data
[src
];
285 copy_pv_tab
[SWSETUP_CONTEXT(ctx
)->SetupIndex
](ctx
, dst
, src
);
291 /***********************************************************************
293 ***********************************************************************/
296 emit_invalid( GLcontext
*ctx
, GLuint start
, GLuint end
, GLuint newinputs
)
298 _mesa_debug(ctx
, "swrast_setup: invalid setup function\n");
299 (void) (ctx
&& start
&& end
&& newinputs
);
304 interp_invalid( GLcontext
*ctx
, GLfloat t
,
305 GLuint edst
, GLuint eout
, GLuint ein
,
306 GLboolean force_boundary
)
308 _mesa_debug(ctx
, "swrast_setup: invalid interp function\n");
309 (void) (ctx
&& t
&& edst
&& eout
&& ein
&& force_boundary
);
314 copy_pv_invalid( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
316 _mesa_debug(ctx
, "swrast_setup: invalid copy_pv function\n");
317 (void) (ctx
&& edst
&& esrc
);
321 static void init_standard( void )
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
;
335 init_color_spec_fog();
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();
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();
359 init_index_fog_point();
366 printSetupFlags(const GLcontext
*ctx
, char *msg
, GLuint flags
)
368 _mesa_debug(ctx
, "%s(%x): %s%s%s%s%s%s%s\n",
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, " : "");
382 _swsetup_choose_rastersetup_func(GLcontext
*ctx
)
384 SScontext
*swsetup
= SWSETUP_CONTEXT(ctx
);
385 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
388 if (ctx
->RenderMode
== GL_RENDER
) {
389 if (ctx
->Visual
.rgbMode
) {
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 */
397 if (ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
)
404 if (ctx
->Point
._Attenuated
||
405 (ctx
->VertexProgram
.Enabled
&& ctx
->VertexProgram
.PointSizeEnabled
))
408 if (ctx
->Fog
.Enabled
)
411 else if (ctx
->RenderMode
== GL_FEEDBACK
) {
412 if (ctx
->Visual
.rgbMode
)
413 funcindex
= (COLOR
| TEX0
); /* is feedback color subject to fogging? */
420 swsetup
->SetupIndex
= funcindex
;
421 tnl
->Driver
.Render
.BuildVertices
= setup_tab
[funcindex
];
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
;
428 tnl
->Driver
.Render
.Interp
= interp_tab
[funcindex
];
429 tnl
->Driver
.Render
.CopyPV
= copy_pv_tab
[funcindex
];
432 ASSERT(tnl
->Driver
.Render
.BuildVertices
);
433 ASSERT(tnl
->Driver
.Render
.BuildVertices
!= emit_invalid
);
438 _swsetup_vb_init( GLcontext
*ctx
)
443 printSetupFlags(ctx);