Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
57 | pj | 1 | /* $Id: s_context.c,v 1.1 2003-02-28 11:49:41 pj 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 <keith@tungstengraphics.com> |
||
28 | */ |
||
29 | |||
30 | #include "glheader.h" |
||
31 | #include "context.h" |
||
32 | #include "mtypes.h" |
||
33 | #include "imports.h" |
||
34 | |||
35 | #include "swrast.h" |
||
36 | #include "s_blend.h" |
||
37 | #include "s_context.h" |
||
38 | #include "s_lines.h" |
||
39 | #include "s_points.h" |
||
40 | #include "s_span.h" |
||
41 | #include "s_triangle.h" |
||
42 | #include "s_texture.h" |
||
43 | |||
44 | |||
45 | /* |
||
46 | * Recompute the value of swrast->_RasterMask, etc. according to |
||
47 | * the current context. |
||
48 | */ |
||
49 | static void |
||
50 | _swrast_update_rasterflags( GLcontext *ctx ) |
||
51 | { |
||
52 | GLuint RasterMask = 0; |
||
53 | |||
54 | if (ctx->Color.AlphaEnabled) RasterMask |= ALPHATEST_BIT; |
||
55 | if (ctx->Color.BlendEnabled) RasterMask |= BLEND_BIT; |
||
56 | if (ctx->Depth.Test) RasterMask |= DEPTH_BIT; |
||
57 | if (ctx->Fog.Enabled) RasterMask |= FOG_BIT; |
||
58 | if (ctx->Scissor.Enabled) RasterMask |= CLIP_BIT; |
||
59 | if (ctx->Stencil.Enabled) RasterMask |= STENCIL_BIT; |
||
60 | if (ctx->Visual.rgbMode) { |
||
61 | const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); |
||
62 | if (colorMask != 0xffffffff) RasterMask |= MASKING_BIT; |
||
63 | if (ctx->Color.ColorLogicOpEnabled) RasterMask |= LOGIC_OP_BIT; |
||
64 | if (ctx->Texture._EnabledUnits) RasterMask |= TEXTURE_BIT; |
||
65 | } |
||
66 | else { |
||
67 | if (ctx->Color.IndexMask != 0xffffffff) RasterMask |= MASKING_BIT; |
||
68 | if (ctx->Color.IndexLogicOpEnabled) RasterMask |= LOGIC_OP_BIT; |
||
69 | } |
||
70 | |||
71 | if (ctx->DrawBuffer->UseSoftwareAlphaBuffers |
||
72 | && ctx->Color.ColorMask[ACOMP] |
||
73 | && ctx->Color.DrawBuffer != GL_NONE) |
||
74 | RasterMask |= ALPHABUF_BIT; |
||
75 | |||
76 | if ( ctx->Viewport.X < 0 |
||
77 | || ctx->Viewport.X + ctx->Viewport.Width > (GLint) ctx->DrawBuffer->Width |
||
78 | || ctx->Viewport.Y < 0 |
||
79 | || ctx->Viewport.Y + ctx->Viewport.Height > (GLint) ctx->DrawBuffer->Height) { |
||
80 | RasterMask |= CLIP_BIT; |
||
81 | } |
||
82 | |||
83 | if (ctx->Depth.OcclusionTest) |
||
84 | RasterMask |= OCCLUSION_BIT; |
||
85 | |||
86 | |||
87 | /* If we're not drawing to exactly one color buffer set the |
||
88 | * MULTI_DRAW_BIT flag. Also set it if we're drawing to no |
||
89 | * buffers or the RGBA or CI mask disables all writes. |
||
90 | */ |
||
91 | if (ctx->Color._DrawDestMask != FRONT_LEFT_BIT && |
||
92 | ctx->Color._DrawDestMask != BACK_LEFT_BIT && |
||
93 | ctx->Color._DrawDestMask != FRONT_RIGHT_BIT && |
||
94 | ctx->Color._DrawDestMask != BACK_RIGHT_BIT) { |
||
95 | /* more than one color buffer designated for writing (or zero buffers) */ |
||
96 | RasterMask |= MULTI_DRAW_BIT; |
||
97 | } |
||
98 | else if (ctx->Visual.rgbMode && *((GLuint *) ctx->Color.ColorMask) == 0) { |
||
99 | RasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */ |
||
100 | } |
||
101 | else if (!ctx->Visual.rgbMode && ctx->Color.IndexMask==0) { |
||
102 | RasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */ |
||
103 | } |
||
104 | |||
105 | SWRAST_CONTEXT(ctx)->_RasterMask = RasterMask; |
||
106 | } |
||
107 | |||
108 | |||
109 | static void |
||
110 | _swrast_update_polygon( GLcontext *ctx ) |
||
111 | { |
||
112 | GLfloat backface_sign = 1; |
||
113 | |||
114 | if (ctx->Polygon.CullFlag) { |
||
115 | backface_sign = 1; |
||
116 | switch(ctx->Polygon.CullFaceMode) { |
||
117 | case GL_BACK: |
||
118 | if(ctx->Polygon.FrontFace==GL_CCW) |
||
119 | backface_sign = -1; |
||
120 | break; |
||
121 | case GL_FRONT: |
||
122 | if(ctx->Polygon.FrontFace!=GL_CCW) |
||
123 | backface_sign = -1; |
||
124 | break; |
||
125 | default: |
||
126 | case GL_FRONT_AND_BACK: |
||
127 | backface_sign = 0; |
||
128 | break; |
||
129 | } |
||
130 | } |
||
131 | else { |
||
132 | backface_sign = 0; |
||
133 | } |
||
134 | |||
135 | SWRAST_CONTEXT(ctx)->_backface_sign = backface_sign; |
||
136 | } |
||
137 | |||
138 | |||
139 | static void |
||
140 | _swrast_update_hint( GLcontext *ctx ) |
||
141 | { |
||
142 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
143 | swrast->_PreferPixelFog = (!swrast->AllowVertexFog || |
||
144 | (ctx->Hint.Fog == GL_NICEST && |
||
145 | swrast->AllowPixelFog)); |
||
146 | } |
||
147 | |||
148 | |||
149 | /* |
||
150 | * Update the swrast->_AnyTextureCombine flag. |
||
151 | */ |
||
152 | static void |
||
153 | _swrast_update_texture_env( GLcontext *ctx ) |
||
154 | { |
||
155 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
156 | GLuint i; |
||
157 | swrast->_AnyTextureCombine = GL_FALSE; |
||
158 | for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { |
||
159 | if (ctx->Texture.Unit[i].EnvMode == GL_COMBINE_EXT || |
||
160 | ctx->Texture.Unit[i].EnvMode == GL_COMBINE4_NV) { |
||
161 | swrast->_AnyTextureCombine = GL_TRUE; |
||
162 | return; |
||
163 | } |
||
164 | } |
||
165 | } |
||
166 | |||
167 | |||
168 | #define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK | \ |
||
169 | _NEW_TEXTURE | \ |
||
170 | _NEW_HINT | \ |
||
171 | _NEW_POLYGON ) |
||
172 | |||
173 | /* State referenced by _swrast_choose_triangle, _swrast_choose_line. |
||
174 | */ |
||
175 | #define _SWRAST_NEW_TRIANGLE (_SWRAST_NEW_DERIVED | \ |
||
176 | _NEW_RENDERMODE| \ |
||
177 | _NEW_POLYGON| \ |
||
178 | _NEW_DEPTH| \ |
||
179 | _NEW_STENCIL| \ |
||
180 | _NEW_COLOR| \ |
||
181 | _NEW_TEXTURE| \ |
||
182 | _SWRAST_NEW_RASTERMASK| \ |
||
183 | _NEW_LIGHT| \ |
||
184 | _NEW_FOG | \ |
||
185 | _DD_NEW_SEPARATE_SPECULAR) |
||
186 | |||
187 | #define _SWRAST_NEW_LINE (_SWRAST_NEW_DERIVED | \ |
||
188 | _NEW_RENDERMODE| \ |
||
189 | _NEW_LINE| \ |
||
190 | _NEW_TEXTURE| \ |
||
191 | _NEW_LIGHT| \ |
||
192 | _NEW_FOG| \ |
||
193 | _NEW_DEPTH | \ |
||
194 | _DD_NEW_SEPARATE_SPECULAR) |
||
195 | |||
196 | #define _SWRAST_NEW_POINT (_SWRAST_NEW_DERIVED | \ |
||
197 | _NEW_RENDERMODE | \ |
||
198 | _NEW_POINT | \ |
||
199 | _NEW_TEXTURE | \ |
||
200 | _NEW_LIGHT | \ |
||
201 | _NEW_FOG | \ |
||
202 | _DD_NEW_SEPARATE_SPECULAR) |
||
203 | |||
204 | #define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE |
||
205 | |||
206 | #define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE |
||
207 | |||
208 | #define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR |
||
209 | |||
210 | |||
211 | |||
212 | /* Stub for swrast->Triangle to select a true triangle function |
||
213 | * after a state change. |
||
214 | */ |
||
215 | static void |
||
216 | _swrast_validate_triangle( GLcontext *ctx, |
||
217 | const SWvertex *v0, |
||
218 | const SWvertex *v1, |
||
219 | const SWvertex *v2 ) |
||
220 | { |
||
221 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
222 | |||
223 | _swrast_validate_derived( ctx ); |
||
224 | swrast->choose_triangle( ctx ); |
||
225 | |||
226 | if ((ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) && |
||
227 | ctx->Texture._EnabledUnits == 0) { |
||
228 | swrast->SpecTriangle = swrast->Triangle; |
||
229 | swrast->Triangle = _swrast_add_spec_terms_triangle; |
||
230 | } |
||
231 | |||
232 | swrast->Triangle( ctx, v0, v1, v2 ); |
||
233 | } |
||
234 | |||
235 | static void |
||
236 | _swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) |
||
237 | { |
||
238 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
239 | |||
240 | _swrast_validate_derived( ctx ); |
||
241 | swrast->choose_line( ctx ); |
||
242 | |||
243 | if ((ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) && |
||
244 | ctx->Texture._EnabledUnits == 0) { |
||
245 | swrast->SpecLine = swrast->Line; |
||
246 | swrast->Line = _swrast_add_spec_terms_line; |
||
247 | } |
||
248 | |||
249 | |||
250 | swrast->Line( ctx, v0, v1 ); |
||
251 | } |
||
252 | |||
253 | static void |
||
254 | _swrast_validate_point( GLcontext *ctx, const SWvertex *v0 ) |
||
255 | { |
||
256 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
257 | |||
258 | _swrast_validate_derived( ctx ); |
||
259 | swrast->choose_point( ctx ); |
||
260 | |||
261 | if ((ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) && |
||
262 | ctx->Texture._EnabledUnits == 0) { |
||
263 | swrast->SpecPoint = swrast->Point; |
||
264 | swrast->Point = _swrast_add_spec_terms_point; |
||
265 | } |
||
266 | |||
267 | swrast->Point( ctx, v0 ); |
||
268 | } |
||
269 | |||
270 | static void |
||
271 | _swrast_validate_blend_func( GLcontext *ctx, GLuint n, |
||
272 | const GLubyte mask[], |
||
273 | GLchan src[][4], |
||
274 | CONST GLchan dst[][4] ) |
||
275 | { |
||
276 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
277 | |||
278 | _swrast_validate_derived( ctx ); |
||
279 | _swrast_choose_blend_func( ctx ); |
||
280 | |||
281 | swrast->BlendFunc( ctx, n, mask, src, dst ); |
||
282 | } |
||
283 | |||
284 | |||
285 | static void |
||
286 | _swrast_validate_texture_sample( GLcontext *ctx, GLuint texUnit, |
||
287 | const struct gl_texture_object *tObj, |
||
288 | GLuint n, GLfloat texcoords[][4], |
||
289 | const GLfloat lambda[], GLchan rgba[][4] ) |
||
290 | { |
||
291 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
292 | |||
293 | _swrast_validate_derived( ctx ); |
||
294 | _swrast_choose_texture_sample_func( ctx, texUnit, tObj ); |
||
295 | |||
296 | swrast->TextureSample[texUnit]( ctx, texUnit, tObj, n, texcoords, |
||
297 | lambda, rgba ); |
||
298 | } |
||
299 | |||
300 | |||
301 | static void |
||
302 | _swrast_sleep( GLcontext *ctx, GLuint new_state ) |
||
303 | { |
||
304 | } |
||
305 | |||
306 | |||
307 | static void |
||
308 | _swrast_invalidate_state( GLcontext *ctx, GLuint new_state ) |
||
309 | { |
||
310 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
311 | GLuint i; |
||
312 | |||
313 | swrast->NewState |= new_state; |
||
314 | |||
315 | /* After 10 statechanges without any swrast functions being called, |
||
316 | * put the module to sleep. |
||
317 | */ |
||
318 | if (++swrast->StateChanges > 10) { |
||
319 | swrast->InvalidateState = _swrast_sleep; |
||
320 | swrast->NewState = ~0; |
||
321 | new_state = ~0; |
||
322 | } |
||
323 | |||
324 | if (new_state & swrast->invalidate_triangle) |
||
325 | swrast->Triangle = _swrast_validate_triangle; |
||
326 | |||
327 | if (new_state & swrast->invalidate_line) |
||
328 | swrast->Line = _swrast_validate_line; |
||
329 | |||
330 | if (new_state & swrast->invalidate_point) |
||
331 | swrast->Point = _swrast_validate_point; |
||
332 | |||
333 | if (new_state & _SWRAST_NEW_BLEND_FUNC) |
||
334 | swrast->BlendFunc = _swrast_validate_blend_func; |
||
335 | |||
336 | if (new_state & _SWRAST_NEW_TEXTURE_SAMPLE_FUNC) |
||
337 | for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) |
||
338 | swrast->TextureSample[i] = _swrast_validate_texture_sample; |
||
339 | |||
340 | if (ctx->Visual.rgbMode) { |
||
341 | ASSERT(swrast->Driver.WriteRGBASpan); |
||
342 | ASSERT(swrast->Driver.WriteRGBSpan); |
||
343 | ASSERT(swrast->Driver.WriteMonoRGBASpan); |
||
344 | ASSERT(swrast->Driver.WriteRGBAPixels); |
||
345 | ASSERT(swrast->Driver.WriteMonoRGBAPixels); |
||
346 | ASSERT(swrast->Driver.ReadRGBASpan); |
||
347 | ASSERT(swrast->Driver.ReadRGBAPixels); |
||
348 | } |
||
349 | else { |
||
350 | ASSERT(swrast->Driver.WriteCI32Span); |
||
351 | ASSERT(swrast->Driver.WriteCI8Span); |
||
352 | ASSERT(swrast->Driver.WriteMonoCISpan); |
||
353 | ASSERT(swrast->Driver.WriteCI32Pixels); |
||
354 | ASSERT(swrast->Driver.WriteMonoCIPixels); |
||
355 | ASSERT(swrast->Driver.ReadCI32Span); |
||
356 | ASSERT(swrast->Driver.ReadCI32Pixels); |
||
357 | } |
||
358 | } |
||
359 | |||
360 | |||
361 | void |
||
362 | _swrast_validate_derived( GLcontext *ctx ) |
||
363 | { |
||
364 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
365 | |||
366 | if (swrast->NewState) { |
||
367 | if (swrast->NewState & _SWRAST_NEW_RASTERMASK) |
||
368 | _swrast_update_rasterflags( ctx ); |
||
369 | |||
370 | if (swrast->NewState & _NEW_POLYGON) |
||
371 | _swrast_update_polygon( ctx ); |
||
372 | |||
373 | if (swrast->NewState & _NEW_HINT) |
||
374 | _swrast_update_hint( ctx ); |
||
375 | |||
376 | if (swrast->NewState & _SWRAST_NEW_TEXTURE_ENV_MODE) |
||
377 | _swrast_update_texture_env( ctx ); |
||
378 | |||
379 | swrast->NewState = 0; |
||
380 | swrast->StateChanges = 0; |
||
381 | swrast->InvalidateState = _swrast_invalidate_state; |
||
382 | } |
||
383 | } |
||
384 | |||
385 | #define SWRAST_DEBUG 0 |
||
386 | |||
387 | /* Public entrypoints: See also s_accum.c, s_bitmap.c, etc. |
||
388 | */ |
||
389 | void |
||
390 | _swrast_Quad( GLcontext *ctx, |
||
391 | const SWvertex *v0, const SWvertex *v1, |
||
392 | const SWvertex *v2, const SWvertex *v3 ) |
||
393 | { |
||
394 | if (SWRAST_DEBUG) { |
||
395 | _mesa_debug(ctx, "_swrast_Quad\n"); |
||
396 | _swrast_print_vertex( ctx, v0 ); |
||
397 | _swrast_print_vertex( ctx, v1 ); |
||
398 | _swrast_print_vertex( ctx, v2 ); |
||
399 | _swrast_print_vertex( ctx, v3 ); |
||
400 | } |
||
401 | SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v3 ); |
||
402 | SWRAST_CONTEXT(ctx)->Triangle( ctx, v1, v2, v3 ); |
||
403 | } |
||
404 | |||
405 | void |
||
406 | _swrast_Triangle( GLcontext *ctx, const SWvertex *v0, |
||
407 | const SWvertex *v1, const SWvertex *v2 ) |
||
408 | { |
||
409 | if (SWRAST_DEBUG) { |
||
410 | _mesa_debug(ctx, "_swrast_Triangle\n"); |
||
411 | _swrast_print_vertex( ctx, v0 ); |
||
412 | _swrast_print_vertex( ctx, v1 ); |
||
413 | _swrast_print_vertex( ctx, v2 ); |
||
414 | } |
||
415 | SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 ); |
||
416 | } |
||
417 | |||
418 | void |
||
419 | _swrast_Line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) |
||
420 | { |
||
421 | if (SWRAST_DEBUG) { |
||
422 | _mesa_debug(ctx, "_swrast_Line\n"); |
||
423 | _swrast_print_vertex( ctx, v0 ); |
||
424 | _swrast_print_vertex( ctx, v1 ); |
||
425 | } |
||
426 | SWRAST_CONTEXT(ctx)->Line( ctx, v0, v1 ); |
||
427 | } |
||
428 | |||
429 | void |
||
430 | _swrast_Point( GLcontext *ctx, const SWvertex *v0 ) |
||
431 | { |
||
432 | if (SWRAST_DEBUG) { |
||
433 | _mesa_debug(ctx, "_swrast_Point\n"); |
||
434 | _swrast_print_vertex( ctx, v0 ); |
||
435 | } |
||
436 | SWRAST_CONTEXT(ctx)->Point( ctx, v0 ); |
||
437 | } |
||
438 | |||
439 | void |
||
440 | _swrast_InvalidateState( GLcontext *ctx, GLuint new_state ) |
||
441 | { |
||
442 | if (SWRAST_DEBUG) { |
||
443 | _mesa_debug(ctx, "_swrast_InvalidateState\n"); |
||
444 | } |
||
445 | SWRAST_CONTEXT(ctx)->InvalidateState( ctx, new_state ); |
||
446 | } |
||
447 | |||
448 | void |
||
449 | _swrast_ResetLineStipple( GLcontext *ctx ) |
||
450 | { |
||
451 | if (SWRAST_DEBUG) { |
||
452 | _mesa_debug(ctx, "_swrast_ResetLineStipple\n"); |
||
453 | } |
||
454 | SWRAST_CONTEXT(ctx)->StippleCounter = 0; |
||
455 | } |
||
456 | |||
457 | void |
||
458 | _swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value ) |
||
459 | { |
||
460 | if (SWRAST_DEBUG) { |
||
461 | _mesa_debug(ctx, "_swrast_allow_vertex_fog %d\n", value); |
||
462 | } |
||
463 | SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); |
||
464 | SWRAST_CONTEXT(ctx)->AllowVertexFog = value; |
||
465 | } |
||
466 | |||
467 | void |
||
468 | _swrast_allow_pixel_fog( GLcontext *ctx, GLboolean value ) |
||
469 | { |
||
470 | if (SWRAST_DEBUG) { |
||
471 | _mesa_debug(ctx, "_swrast_allow_pixel_fog %d\n", value); |
||
472 | } |
||
473 | SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); |
||
474 | SWRAST_CONTEXT(ctx)->AllowPixelFog = value; |
||
475 | } |
||
476 | |||
477 | |||
478 | GLboolean |
||
479 | _swrast_CreateContext( GLcontext *ctx ) |
||
480 | { |
||
481 | GLuint i; |
||
482 | SWcontext *swrast = (SWcontext *)CALLOC(sizeof(SWcontext)); |
||
483 | |||
484 | if (SWRAST_DEBUG) { |
||
485 | _mesa_debug(ctx, "_swrast_CreateContext\n"); |
||
486 | } |
||
487 | |||
488 | if (!swrast) |
||
489 | return GL_FALSE; |
||
490 | |||
491 | swrast->NewState = ~0; |
||
492 | |||
493 | swrast->choose_point = _swrast_choose_point; |
||
494 | swrast->choose_line = _swrast_choose_line; |
||
495 | swrast->choose_triangle = _swrast_choose_triangle; |
||
496 | |||
497 | swrast->invalidate_point = _SWRAST_NEW_POINT; |
||
498 | swrast->invalidate_line = _SWRAST_NEW_LINE; |
||
499 | swrast->invalidate_triangle = _SWRAST_NEW_TRIANGLE; |
||
500 | |||
501 | swrast->Point = _swrast_validate_point; |
||
502 | swrast->Line = _swrast_validate_line; |
||
503 | swrast->Triangle = _swrast_validate_triangle; |
||
504 | swrast->InvalidateState = _swrast_sleep; |
||
505 | swrast->BlendFunc = _swrast_validate_blend_func; |
||
506 | |||
507 | swrast->AllowVertexFog = GL_TRUE; |
||
508 | swrast->AllowPixelFog = GL_TRUE; |
||
509 | |||
510 | if (ctx->Visual.doubleBufferMode) |
||
511 | swrast->CurrentBuffer = BACK_LEFT_BIT; |
||
512 | else |
||
513 | swrast->CurrentBuffer = FRONT_LEFT_BIT; |
||
514 | |||
515 | /* Optimized Accum buffer */ |
||
516 | swrast->_IntegerAccumMode = GL_TRUE; |
||
517 | swrast->_IntegerAccumScaler = 0.0; |
||
518 | |||
519 | for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) |
||
520 | swrast->TextureSample[i] = _swrast_validate_texture_sample; |
||
521 | |||
522 | swrast->SpanArrays = MALLOC_STRUCT(span_arrays); |
||
523 | if (!swrast->SpanArrays) { |
||
524 | FREE(swrast); |
||
525 | return GL_FALSE; |
||
526 | } |
||
527 | |||
528 | /* init point span buffer */ |
||
529 | swrast->PointSpan.primitive = GL_POINT; |
||
530 | swrast->PointSpan.start = 0; |
||
531 | swrast->PointSpan.end = 0; |
||
532 | swrast->PointSpan.facing = 0; |
||
533 | swrast->PointSpan.array = swrast->SpanArrays; |
||
534 | |||
535 | assert(ctx->Const.MaxTextureUnits > 0); |
||
536 | assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_UNITS); |
||
537 | |||
538 | swrast->TexelBuffer = (GLchan *) MALLOC(ctx->Const.MaxTextureUnits * |
||
539 | MAX_WIDTH * 4 * sizeof(GLchan)); |
||
540 | if (!swrast->TexelBuffer) { |
||
541 | FREE(swrast->SpanArrays); |
||
542 | FREE(swrast); |
||
543 | return GL_FALSE; |
||
544 | } |
||
545 | |||
546 | ctx->swrast_context = swrast; |
||
547 | |||
548 | return GL_TRUE; |
||
549 | } |
||
550 | |||
551 | void |
||
552 | _swrast_DestroyContext( GLcontext *ctx ) |
||
553 | { |
||
554 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
555 | |||
556 | if (SWRAST_DEBUG) { |
||
557 | _mesa_debug(ctx, "_swrast_DestroyContext\n"); |
||
558 | } |
||
559 | |||
560 | FREE( swrast->SpanArrays ); |
||
561 | FREE( swrast->TexelBuffer ); |
||
562 | FREE( swrast ); |
||
563 | |||
564 | ctx->swrast_context = 0; |
||
565 | } |
||
566 | |||
567 | |||
568 | struct swrast_device_driver * |
||
569 | _swrast_GetDeviceDriverReference( GLcontext *ctx ) |
||
570 | { |
||
571 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
572 | return &swrast->Driver; |
||
573 | } |
||
574 | |||
575 | void |
||
576 | _swrast_flush( GLcontext *ctx ) |
||
577 | { |
||
578 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
579 | /* flush any pending fragments from rendering points */ |
||
580 | if (swrast->PointSpan.end > 0) { |
||
581 | if (ctx->Visual.rgbMode) { |
||
582 | if (ctx->Texture._EnabledUnits) |
||
583 | _mesa_write_texture_span(ctx, &(swrast->PointSpan)); |
||
584 | else |
||
585 | _mesa_write_rgba_span(ctx, &(swrast->PointSpan)); |
||
586 | } |
||
587 | else { |
||
588 | _mesa_write_index_span(ctx, &(swrast->PointSpan)); |
||
589 | } |
||
590 | swrast->PointSpan.end = 0; |
||
591 | } |
||
592 | } |
||
593 | |||
594 | void |
||
595 | _swrast_render_primitive( GLcontext *ctx, GLenum prim ) |
||
596 | { |
||
597 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
598 | if (swrast->Primitive == GL_POINTS && prim != GL_POINTS) { |
||
599 | _swrast_flush(ctx); |
||
600 | } |
||
601 | swrast->Primitive = prim; |
||
602 | } |
||
603 | |||
604 | |||
605 | void |
||
606 | _swrast_render_start( GLcontext *ctx ) |
||
607 | { |
||
608 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
609 | if (swrast->Driver.SpanRenderStart) |
||
610 | swrast->Driver.SpanRenderStart( ctx ); |
||
611 | swrast->PointSpan.end = 0; |
||
612 | } |
||
613 | |||
614 | void |
||
615 | _swrast_render_finish( GLcontext *ctx ) |
||
616 | { |
||
617 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
618 | if (swrast->Driver.SpanRenderFinish) |
||
619 | swrast->Driver.SpanRenderFinish( ctx ); |
||
620 | |||
621 | _swrast_flush(ctx); |
||
622 | } |
||
623 | |||
624 | |||
625 | #define SWRAST_DEBUG_VERTICES 0 |
||
626 | |||
627 | void |
||
628 | _swrast_print_vertex( GLcontext *ctx, const SWvertex *v ) |
||
629 | { |
||
630 | GLuint i; |
||
631 | |||
632 | if (SWRAST_DEBUG_VERTICES) { |
||
633 | _mesa_debug(ctx, "win %f %f %f %f\n", |
||
634 | v->win[0], v->win[1], v->win[2], v->win[3]); |
||
635 | |||
636 | for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) |
||
637 | if (ctx->Texture.Unit[i]._ReallyEnabled) |
||
638 | _mesa_debug(ctx, "texcoord[%d] %f %f %f %f\n", i, |
||
639 | v->texcoord[i][0], v->texcoord[i][1], |
||
640 | v->texcoord[i][2], v->texcoord[i][3]); |
||
641 | |||
642 | #if CHAN_TYPE == GL_FLOAT |
||
643 | _mesa_debug(ctx, "color %f %f %f %f\n", |
||
644 | v->color[0], v->color[1], v->color[2], v->color[3]); |
||
645 | _mesa_debug(ctx, "spec %f %f %f %f\n", |
||
646 | v->specular[0], v->specular[1], |
||
647 | v->specular[2], v->specular[3]); |
||
648 | #else |
||
649 | _mesa_debug(ctx, "color %d %d %d %d\n", |
||
650 | v->color[0], v->color[1], v->color[2], v->color[3]); |
||
651 | _mesa_debug(ctx, "spec %d %d %d %d\n", |
||
652 | v->specular[0], v->specular[1], |
||
653 | v->specular[2], v->specular[3]); |
||
654 | #endif |
||
655 | _mesa_debug(ctx, "fog %f\n", v->fog); |
||
656 | _mesa_debug(ctx, "index %d\n", v->index); |
||
657 | _mesa_debug(ctx, "pointsize %f\n", v->pointSize); |
||
658 | _mesa_debug(ctx, "\n"); |
||
659 | } |
||
660 | } |