1 /* $Id: s_context.c,v 1.12 2001/01/29 21:47:13 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999 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>
37 #include "s_triangle.h"
40 #include "s_context.h"
41 #include "s_texture.h"
48 * Recompute the value of swrast->_RasterMask, etc. according to
49 * the current context.
52 _swrast_update_rasterflags( GLcontext
*ctx
)
54 GLuint RasterMask
= 0;
56 if (ctx
->Color
.AlphaEnabled
) RasterMask
|= ALPHATEST_BIT
;
57 if (ctx
->Color
.BlendEnabled
) RasterMask
|= BLEND_BIT
;
58 if (ctx
->Depth
.Test
) RasterMask
|= DEPTH_BIT
;
59 if (ctx
->Fog
.Enabled
) RasterMask
|= FOG_BIT
;
60 if (ctx
->Scissor
.Enabled
) RasterMask
|= SCISSOR_BIT
;
61 if (ctx
->Stencil
.Enabled
) RasterMask
|= STENCIL_BIT
;
62 if (ctx
->Visual
.rgbMode
) {
63 const GLuint colorMask
= *((GLuint
*) &ctx
->Color
.ColorMask
);
64 if (colorMask
!= 0xffffffff) RasterMask
|= MASKING_BIT
;
65 if (ctx
->Color
.ColorLogicOpEnabled
) RasterMask
|= LOGIC_OP_BIT
;
66 if (ctx
->Texture
._ReallyEnabled
) RasterMask
|= TEXTURE_BIT
;
69 if (ctx
->Color
.IndexMask
!= 0xffffffff) RasterMask
|= MASKING_BIT
;
70 if (ctx
->Color
.IndexLogicOpEnabled
) RasterMask
|= LOGIC_OP_BIT
;
73 if (ctx
->DrawBuffer
->UseSoftwareAlphaBuffers
74 && ctx
->Color
.ColorMask
[ACOMP
]
75 && ctx
->Color
.DrawBuffer
!= GL_NONE
)
76 RasterMask
|= ALPHABUF_BIT
;
78 if ( ctx
->Viewport
.X
< 0
79 || ctx
->Viewport
.X
+ ctx
->Viewport
.Width
> ctx
->DrawBuffer
->Width
80 || ctx
->Viewport
.Y
< 0
81 || ctx
->Viewport
.Y
+ ctx
->Viewport
.Height
> ctx
->DrawBuffer
->Height
) {
82 RasterMask
|= WINCLIP_BIT
;
85 if (ctx
->Depth
.OcclusionTest
)
86 RasterMask
|= OCCLUSION_BIT
;
89 /* If we're not drawing to exactly one color buffer set the
90 * MULTI_DRAW_BIT flag. Also set it if we're drawing to no
91 * buffers or the RGBA or CI mask disables all writes.
93 if (ctx
->Color
.MultiDrawBuffer
) {
94 RasterMask
|= MULTI_DRAW_BIT
;
96 else if (ctx
->Color
.DrawBuffer
==GL_NONE
) {
97 RasterMask
|= MULTI_DRAW_BIT
;
99 else if (ctx
->Visual
.rgbMode
&& *((GLuint
*) ctx
->Color
.ColorMask
) == 0) {
100 RasterMask
|= MULTI_DRAW_BIT
; /* all RGBA channels disabled */
102 else if (!ctx
->Visual
.rgbMode
&& ctx
->Color
.IndexMask
==0) {
103 RasterMask
|= MULTI_DRAW_BIT
; /* all color index bits disabled */
106 if ( ctx
->Viewport
.X
<0
107 || ctx
->Viewport
.X
+ ctx
->Viewport
.Width
> ctx
->DrawBuffer
->Width
109 || ctx
->Viewport
.Y
+ ctx
->Viewport
.Height
> ctx
->DrawBuffer
->Height
) {
110 RasterMask
|= WINCLIP_BIT
;
113 SWRAST_CONTEXT(ctx
)->_RasterMask
= RasterMask
;
118 _swrast_update_polygon( GLcontext
*ctx
)
120 GLfloat backface_sign
= 1;
122 if (ctx
->Polygon
.CullFlag
) {
124 switch(ctx
->Polygon
.CullFaceMode
) {
126 if(ctx
->Polygon
.FrontFace
==GL_CCW
)
130 if(ctx
->Polygon
.FrontFace
!=GL_CCW
)
134 case GL_FRONT_AND_BACK
:
143 SWRAST_CONTEXT(ctx
)->_backface_sign
= backface_sign
;
148 _swrast_update_hint( GLcontext
*ctx
)
150 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
151 swrast
->_PreferPixelFog
= (!swrast
->AllowVertexFog
||
152 (ctx
->Hint
.Fog
== GL_NICEST
&&
153 swrast
->AllowPixelFog
));
156 #define _SWRAST_NEW_TRIANGLE (_NEW_RENDERMODE| \
163 _SWRAST_NEW_RASTERMASK| \
167 #define _SWRAST_NEW_LINE (_NEW_RENDERMODE| \
174 #define _SWRAST_NEW_POINT (_NEW_RENDERMODE | \
180 #define _SWRAST_NEW_QUAD 0
182 #define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE
184 #define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR
188 /* Stub for swrast->Triangle to select a true triangle function
189 * after a state change.
192 _swrast_validate_quad( GLcontext
*ctx
,
193 const SWvertex
*v0
, const SWvertex
*v1
,
194 const SWvertex
*v2
, const SWvertex
*v3
)
196 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
198 _swrast_validate_derived( ctx
);
199 swrast
->choose_quad( ctx
);
201 swrast
->Quad( ctx
, v0
, v1
, v2
, v3
);
205 _swrast_validate_triangle( GLcontext
*ctx
,
210 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
212 _swrast_validate_derived( ctx
);
213 swrast
->choose_triangle( ctx
);
215 swrast
->Triangle( ctx
, v0
, v1
, v2
);
219 _swrast_validate_line( GLcontext
*ctx
, const SWvertex
*v0
, const SWvertex
*v1
)
221 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
223 _swrast_validate_derived( ctx
);
224 swrast
->choose_line( ctx
);
226 swrast
->Line( ctx
, v0
, v1
);
230 _swrast_validate_point( GLcontext
*ctx
, const SWvertex
*v0
)
232 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
234 _swrast_validate_derived( ctx
);
235 swrast
->choose_point( ctx
);
237 swrast
->Point( ctx
, v0
);
241 _swrast_validate_blend_func( GLcontext
*ctx
, GLuint n
,
242 const GLubyte mask
[],
244 CONST GLchan dst
[][4] )
246 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
248 _swrast_validate_derived( ctx
);
249 _swrast_choose_blend_func( ctx
);
251 swrast
->BlendFunc( ctx
, n
, mask
, src
, dst
);
256 _swrast_validate_texture_sample( GLcontext
*ctx
, GLuint texUnit
,
257 const struct gl_texture_object
*tObj
,
259 const GLfloat s
[], const GLfloat t
[],
260 const GLfloat u
[], const GLfloat lambda
[],
263 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
265 _swrast_validate_derived( ctx
);
266 _swrast_choose_texture_sample_func( ctx
, texUnit
, tObj
);
268 swrast
->TextureSample
[texUnit
]( ctx
, texUnit
, tObj
, n
, s
, t
, u
,
274 _swrast_sleep( GLcontext
*ctx
, GLuint new_state
)
280 _swrast_invalidate_state( GLcontext
*ctx
, GLuint new_state
)
282 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
285 swrast
->NewState
|= new_state
;
287 /* After 10 statechanges without any swrast functions being called,
288 * put the module to sleep.
290 if (++swrast
->StateChanges
> 10) {
291 swrast
->InvalidateState
= _swrast_sleep
;
292 swrast
->NewState
= ~0;
296 if (new_state
& swrast
->invalidate_triangle
)
297 swrast
->Triangle
= _swrast_validate_triangle
;
299 if (new_state
& swrast
->invalidate_line
)
300 swrast
->Line
= _swrast_validate_line
;
302 if (new_state
& swrast
->invalidate_point
)
303 swrast
->Point
= _swrast_validate_point
;
305 if (new_state
& swrast
->invalidate_quad
)
306 swrast
->Quad
= _swrast_validate_quad
;
308 if (new_state
& _SWRAST_NEW_BLEND_FUNC
)
309 swrast
->BlendFunc
= _swrast_validate_blend_func
;
311 if (new_state
& _SWRAST_NEW_TEXTURE_SAMPLE_FUNC
)
312 for (i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++)
313 swrast
->TextureSample
[i
] = _swrast_validate_texture_sample
;
319 _swrast_validate_derived( GLcontext
*ctx
)
321 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
323 if (swrast
->NewState
)
325 if (swrast
->NewState
& _SWRAST_NEW_RASTERMASK
)
326 _swrast_update_rasterflags( ctx
);
328 if (swrast
->NewState
& _NEW_TEXTURE
)
329 swrast
->_MultiTextureEnabled
=
330 ctx
->Texture
._ReallyEnabled
> TEXTURE0_ANY
;
332 if (swrast
->NewState
& _NEW_POLYGON
)
333 _swrast_update_polygon( ctx
);
335 if (swrast
->NewState
& _NEW_HINT
)
336 _swrast_update_hint( ctx
);
338 swrast
->NewState
= 0;
339 swrast
->StateChanges
= 0;
340 swrast
->InvalidateState
= _swrast_invalidate_state
;
346 /* Public entrypoints: See also s_accum.c, s_bitmap.c, etc.
349 _swrast_Quad( GLcontext
*ctx
,
350 const SWvertex
*v0
, const SWvertex
*v1
,
351 const SWvertex
*v2
, const SWvertex
*v3
)
353 /* fprintf(stderr, "%s\n", __FUNCTION__); */
354 /* _swrast_print_vertex( ctx, v0 ); */
355 /* _swrast_print_vertex( ctx, v1 ); */
356 /* _swrast_print_vertex( ctx, v2 ); */
357 /* _swrast_print_vertex( ctx, v3 ); */
358 SWRAST_CONTEXT(ctx
)->Quad( ctx
, v0
, v1
, v2
, v3
);
362 _swrast_Triangle( GLcontext
*ctx
, const SWvertex
*v0
,
363 const SWvertex
*v1
, const SWvertex
*v2
)
365 /* fprintf(stderr, "%s\n", __FUNCTION__); */
366 /* _swrast_print_vertex( ctx, v0 ); */
367 /* _swrast_print_vertex( ctx, v1 ); */
368 /* _swrast_print_vertex( ctx, v2 ); */
369 SWRAST_CONTEXT(ctx
)->Triangle( ctx
, v0
, v1
, v2
);
373 _swrast_Line( GLcontext
*ctx
, const SWvertex
*v0
, const SWvertex
*v1
)
375 /* fprintf(stderr, "%s\n", __FUNCTION__); */
376 /* _swrast_print_vertex( ctx, v0 ); */
377 /* _swrast_print_vertex( ctx, v1 ); */
378 SWRAST_CONTEXT(ctx
)->Line( ctx
, v0
, v1
);
382 _swrast_Point( GLcontext
*ctx
, const SWvertex
*v0
)
384 /* fprintf(stderr, "%s\n", __FUNCTION__); */
385 /* _swrast_print_vertex( ctx, v0 ); */
386 SWRAST_CONTEXT(ctx
)->Point( ctx
, v0
);
390 _swrast_InvalidateState( GLcontext
*ctx
, GLuint new_state
)
392 SWRAST_CONTEXT(ctx
)->InvalidateState( ctx
, new_state
);
396 _swrast_ResetLineStipple( GLcontext
*ctx
)
398 SWRAST_CONTEXT(ctx
)->StippleCounter
= 0;
402 _swrast_allow_vertex_fog( GLcontext
*ctx
, GLboolean value
)
404 SWRAST_CONTEXT(ctx
)->InvalidateState( ctx
, _NEW_HINT
);
405 SWRAST_CONTEXT(ctx
)->AllowVertexFog
= value
;
409 _swrast_allow_pixel_fog( GLcontext
*ctx
, GLboolean value
)
411 SWRAST_CONTEXT(ctx
)->InvalidateState( ctx
, _NEW_HINT
);
412 SWRAST_CONTEXT(ctx
)->AllowPixelFog
= value
;
417 _swrast_CreateContext( GLcontext
*ctx
)
420 SWcontext
*swrast
= (SWcontext
*)CALLOC(sizeof(SWcontext
));
424 swrast
->PB
= gl_alloc_pb();
430 swrast
->NewState
= ~0;
432 swrast
->choose_point
= _swrast_choose_point
;
433 swrast
->choose_line
= _swrast_choose_line
;
434 swrast
->choose_triangle
= _swrast_choose_triangle
;
435 swrast
->choose_quad
= _swrast_choose_quad
;
437 swrast
->invalidate_point
= _SWRAST_NEW_POINT
;
438 swrast
->invalidate_line
= _SWRAST_NEW_LINE
;
439 swrast
->invalidate_triangle
= _SWRAST_NEW_TRIANGLE
;
440 swrast
->invalidate_quad
= _SWRAST_NEW_QUAD
;
442 swrast
->Point
= _swrast_validate_point
;
443 swrast
->Line
= _swrast_validate_line
;
444 swrast
->Triangle
= _swrast_validate_triangle
;
445 swrast
->Quad
= _swrast_validate_quad
;
446 swrast
->InvalidateState
= _swrast_sleep
;
447 swrast
->BlendFunc
= _swrast_validate_blend_func
;
449 swrast
->AllowVertexFog
= GL_TRUE
;
450 swrast
->AllowPixelFog
= GL_TRUE
;
452 /* Optimized Accum buffer */
453 swrast
->_IntegerAccumMode
= GL_TRUE
;
454 swrast
->_IntegerAccumScaler
= 0.0;
457 for (i
= 0 ; i
< MAX_TEXTURE_UNITS
; i
++)
458 swrast
->TextureSample
[i
] = _swrast_validate_texture_sample
;
460 ctx
->swrast_context
= swrast
;
465 _swrast_DestroyContext( GLcontext
*ctx
)
467 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
472 ctx
->swrast_context
= 0;
477 _swrast_print_vertex( GLcontext
*ctx
, const SWvertex
*v
)
481 fprintf(stderr
, "win %f %f %f %f\n",
482 v
->win
[0], v
->win
[1], v
->win
[2], v
->win
[3]);
484 for (i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++)
485 fprintf(stderr
, "texcoord[%d] %f %f %f %f\n", i
,
486 v
->texcoord
[i
][0], v
->texcoord
[i
][1],
487 v
->texcoord
[i
][2], v
->texcoord
[i
][3]);
489 fprintf(stderr
, "color %d %d %d %d\n",
490 v
->color
[0], v
->color
[1], v
->color
[2], v
->color
[3]);
491 fprintf(stderr
, "spec %d %d %d %d\n",
492 v
->specular
[0], v
->specular
[1], v
->specular
[2], v
->specular
[3]);
493 fprintf(stderr
, "fog %f\n", v
->fog
);
494 fprintf(stderr
, "index %d\n", v
->index
);
495 fprintf(stderr
, "pointsize %f\n", v
->pointSize
);
496 fprintf(stderr
, "\n");