1 /* $Id: s_context.c,v 1.32 2002/05/02 00:59:20 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>
37 #include "s_triangle.h"
39 #include "s_context.h"
40 #include "s_texture.h"
44 * Recompute the value of swrast->_RasterMask, etc. according to
45 * the current context.
48 _swrast_update_rasterflags( GLcontext
*ctx
)
50 GLuint RasterMask
= 0;
52 if (ctx
->Color
.AlphaEnabled
) RasterMask
|= ALPHATEST_BIT
;
53 if (ctx
->Color
.BlendEnabled
) RasterMask
|= BLEND_BIT
;
54 if (ctx
->Depth
.Test
) RasterMask
|= DEPTH_BIT
;
55 if (ctx
->Fog
.Enabled
) RasterMask
|= FOG_BIT
;
56 if (ctx
->Scissor
.Enabled
) RasterMask
|= CLIP_BIT
;
57 if (ctx
->Stencil
.Enabled
) RasterMask
|= STENCIL_BIT
;
58 if (ctx
->Visual
.rgbMode
) {
59 const GLuint colorMask
= *((GLuint
*) &ctx
->Color
.ColorMask
);
60 if (colorMask
!= 0xffffffff) RasterMask
|= MASKING_BIT
;
61 if (ctx
->Color
.ColorLogicOpEnabled
) RasterMask
|= LOGIC_OP_BIT
;
62 if (ctx
->Texture
._ReallyEnabled
) RasterMask
|= TEXTURE_BIT
;
65 if (ctx
->Color
.IndexMask
!= 0xffffffff) RasterMask
|= MASKING_BIT
;
66 if (ctx
->Color
.IndexLogicOpEnabled
) RasterMask
|= LOGIC_OP_BIT
;
69 if (ctx
->DrawBuffer
->UseSoftwareAlphaBuffers
70 && ctx
->Color
.ColorMask
[ACOMP
]
71 && ctx
->Color
.DrawBuffer
!= GL_NONE
)
72 RasterMask
|= ALPHABUF_BIT
;
74 if ( ctx
->Viewport
.X
< 0
75 || ctx
->Viewport
.X
+ ctx
->Viewport
.Width
> (GLint
) ctx
->DrawBuffer
->Width
76 || ctx
->Viewport
.Y
< 0
77 || ctx
->Viewport
.Y
+ ctx
->Viewport
.Height
> (GLint
) ctx
->DrawBuffer
->Height
) {
78 RasterMask
|= CLIP_BIT
;
81 if (ctx
->Depth
.OcclusionTest
)
82 RasterMask
|= OCCLUSION_BIT
;
85 /* If we're not drawing to exactly one color buffer set the
86 * MULTI_DRAW_BIT flag. Also set it if we're drawing to no
87 * buffers or the RGBA or CI mask disables all writes.
89 if (ctx
->Color
.MultiDrawBuffer
) {
90 RasterMask
|= MULTI_DRAW_BIT
;
92 else if (ctx
->Color
.DrawBuffer
==GL_NONE
) {
93 RasterMask
|= MULTI_DRAW_BIT
;
95 else if (ctx
->Visual
.rgbMode
&& *((GLuint
*) ctx
->Color
.ColorMask
) == 0) {
96 RasterMask
|= MULTI_DRAW_BIT
; /* all RGBA channels disabled */
98 else if (!ctx
->Visual
.rgbMode
&& ctx
->Color
.IndexMask
==0) {
99 RasterMask
|= MULTI_DRAW_BIT
; /* all color index bits disabled */
102 SWRAST_CONTEXT(ctx
)->_RasterMask
= RasterMask
;
107 _swrast_update_polygon( GLcontext
*ctx
)
109 GLfloat backface_sign
= 1;
111 if (ctx
->Polygon
.CullFlag
) {
113 switch(ctx
->Polygon
.CullFaceMode
) {
115 if(ctx
->Polygon
.FrontFace
==GL_CCW
)
119 if(ctx
->Polygon
.FrontFace
!=GL_CCW
)
123 case GL_FRONT_AND_BACK
:
132 SWRAST_CONTEXT(ctx
)->_backface_sign
= backface_sign
;
137 _swrast_update_hint( GLcontext
*ctx
)
139 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
140 swrast
->_PreferPixelFog
= (!swrast
->AllowVertexFog
||
141 (ctx
->Hint
.Fog
== GL_NICEST
&&
142 swrast
->AllowPixelFog
));
147 * Update the swrast->_AnyTextureCombine flag.
150 _swrast_update_texture_env( GLcontext
*ctx
)
152 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
154 swrast
->_AnyTextureCombine
= GL_FALSE
;
155 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
156 if (ctx
->Texture
.Unit
[i
].EnvMode
== GL_COMBINE_EXT
||
157 ctx
->Texture
.Unit
[i
].EnvMode
== GL_COMBINE4_NV
) {
158 swrast
->_AnyTextureCombine
= GL_TRUE
;
165 #define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK | \
170 /* State referenced by _swrast_choose_triangle, _swrast_choose_line.
172 #define _SWRAST_NEW_TRIANGLE (_SWRAST_NEW_DERIVED | \
179 _SWRAST_NEW_RASTERMASK| \
182 _DD_NEW_SEPARATE_SPECULAR)
184 #define _SWRAST_NEW_LINE (_SWRAST_NEW_DERIVED | \
191 _DD_NEW_SEPARATE_SPECULAR)
193 #define _SWRAST_NEW_POINT (_SWRAST_NEW_DERIVED | \
199 _DD_NEW_SEPARATE_SPECULAR)
201 #define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE
203 #define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE
205 #define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR
209 /* Stub for swrast->Triangle to select a true triangle function
210 * after a state change.
213 _swrast_validate_triangle( GLcontext
*ctx
,
218 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
220 _swrast_validate_derived( ctx
);
221 swrast
->choose_triangle( ctx
);
223 if ((ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
) &&
224 !ctx
->Texture
._ReallyEnabled
) {
225 swrast
->SpecTriangle
= swrast
->Triangle
;
226 swrast
->Triangle
= _swrast_add_spec_terms_triangle
;
229 swrast
->Triangle( ctx
, v0
, v1
, v2
);
233 _swrast_validate_line( GLcontext
*ctx
, const SWvertex
*v0
, const SWvertex
*v1
)
235 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
237 _swrast_validate_derived( ctx
);
238 swrast
->choose_line( ctx
);
240 if ((ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
) &&
241 !ctx
->Texture
._ReallyEnabled
) {
242 swrast
->SpecLine
= swrast
->Line
;
243 swrast
->Line
= _swrast_add_spec_terms_line
;
247 swrast
->Line( ctx
, v0
, v1
);
251 _swrast_validate_point( GLcontext
*ctx
, const SWvertex
*v0
)
253 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
255 _swrast_validate_derived( ctx
);
256 swrast
->choose_point( ctx
);
258 if ((ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
) &&
259 !ctx
->Texture
._ReallyEnabled
) {
260 swrast
->SpecPoint
= swrast
->Point
;
261 swrast
->Point
= _swrast_add_spec_terms_point
;
264 swrast
->Point( ctx
, v0
);
268 _swrast_validate_blend_func( GLcontext
*ctx
, GLuint n
,
269 const GLubyte mask
[],
271 CONST GLchan dst
[][4] )
273 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
275 _swrast_validate_derived( ctx
);
276 _swrast_choose_blend_func( ctx
);
278 swrast
->BlendFunc( ctx
, n
, mask
, src
, dst
);
283 _swrast_validate_texture_sample( GLcontext
*ctx
, GLuint texUnit
,
284 const struct gl_texture_object
*tObj
,
285 GLuint n
, GLfloat texcoords
[][4],
286 const GLfloat lambda
[], GLchan rgba
[][4] )
288 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
290 _swrast_validate_derived( ctx
);
291 _swrast_choose_texture_sample_func( ctx
, texUnit
, tObj
);
293 swrast
->TextureSample
[texUnit
]( ctx
, texUnit
, tObj
, n
, texcoords
,
299 _swrast_sleep( GLcontext
*ctx
, GLuint new_state
)
305 _swrast_invalidate_state( GLcontext
*ctx
, GLuint new_state
)
307 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
310 swrast
->NewState
|= new_state
;
312 /* After 10 statechanges without any swrast functions being called,
313 * put the module to sleep.
315 if (++swrast
->StateChanges
> 10) {
316 swrast
->InvalidateState
= _swrast_sleep
;
317 swrast
->NewState
= ~0;
321 if (new_state
& swrast
->invalidate_triangle
)
322 swrast
->Triangle
= _swrast_validate_triangle
;
324 if (new_state
& swrast
->invalidate_line
)
325 swrast
->Line
= _swrast_validate_line
;
327 if (new_state
& swrast
->invalidate_point
)
328 swrast
->Point
= _swrast_validate_point
;
330 if (new_state
& _SWRAST_NEW_BLEND_FUNC
)
331 swrast
->BlendFunc
= _swrast_validate_blend_func
;
333 if (new_state
& _SWRAST_NEW_TEXTURE_SAMPLE_FUNC
)
334 for (i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++)
335 swrast
->TextureSample
[i
] = _swrast_validate_texture_sample
;
337 if (ctx
->Visual
.rgbMode
) {
338 ASSERT(swrast
->Driver
.WriteRGBASpan
);
339 ASSERT(swrast
->Driver
.WriteRGBSpan
);
340 ASSERT(swrast
->Driver
.WriteMonoRGBASpan
);
341 ASSERT(swrast
->Driver
.WriteRGBAPixels
);
342 ASSERT(swrast
->Driver
.WriteMonoRGBAPixels
);
343 ASSERT(swrast
->Driver
.ReadRGBASpan
);
344 ASSERT(swrast
->Driver
.ReadRGBAPixels
);
347 ASSERT(swrast
->Driver
.WriteCI32Span
);
348 ASSERT(swrast
->Driver
.WriteCI8Span
);
349 ASSERT(swrast
->Driver
.WriteMonoCISpan
);
350 ASSERT(swrast
->Driver
.WriteCI32Pixels
);
351 ASSERT(swrast
->Driver
.WriteMonoCIPixels
);
352 ASSERT(swrast
->Driver
.ReadCI32Span
);
353 ASSERT(swrast
->Driver
.ReadCI32Pixels
);
359 _swrast_validate_derived( GLcontext
*ctx
)
361 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
363 if (swrast
->NewState
) {
364 if (swrast
->NewState
& _SWRAST_NEW_RASTERMASK
)
365 _swrast_update_rasterflags( ctx
);
367 if (swrast
->NewState
& _NEW_POLYGON
)
368 _swrast_update_polygon( ctx
);
370 if (swrast
->NewState
& _NEW_HINT
)
371 _swrast_update_hint( ctx
);
373 if (swrast
->NewState
& _SWRAST_NEW_TEXTURE_ENV_MODE
)
374 _swrast_update_texture_env( ctx
);
376 swrast
->NewState
= 0;
377 swrast
->StateChanges
= 0;
378 swrast
->InvalidateState
= _swrast_invalidate_state
;
382 #define SWRAST_DEBUG 0
384 /* Public entrypoints: See also s_accum.c, s_bitmap.c, etc.
387 _swrast_Quad( GLcontext
*ctx
,
388 const SWvertex
*v0
, const SWvertex
*v1
,
389 const SWvertex
*v2
, const SWvertex
*v3
)
392 fprintf(stderr
, "_swrast_Quad\n");
393 _swrast_print_vertex( ctx
, v0
);
394 _swrast_print_vertex( ctx
, v1
);
395 _swrast_print_vertex( ctx
, v2
);
396 _swrast_print_vertex( ctx
, v3
);
398 SWRAST_CONTEXT(ctx
)->Triangle( ctx
, v0
, v1
, v3
);
399 SWRAST_CONTEXT(ctx
)->Triangle( ctx
, v1
, v2
, v3
);
403 _swrast_Triangle( GLcontext
*ctx
, const SWvertex
*v0
,
404 const SWvertex
*v1
, const SWvertex
*v2
)
407 fprintf(stderr
, "_swrast_Triangle\n");
408 _swrast_print_vertex( ctx
, v0
);
409 _swrast_print_vertex( ctx
, v1
);
410 _swrast_print_vertex( ctx
, v2
);
412 SWRAST_CONTEXT(ctx
)->Triangle( ctx
, v0
, v1
, v2
);
416 _swrast_Line( GLcontext
*ctx
, const SWvertex
*v0
, const SWvertex
*v1
)
419 fprintf(stderr
, "_swrast_Line\n");
420 _swrast_print_vertex( ctx
, v0
);
421 _swrast_print_vertex( ctx
, v1
);
423 SWRAST_CONTEXT(ctx
)->Line( ctx
, v0
, v1
);
427 _swrast_Point( GLcontext
*ctx
, const SWvertex
*v0
)
430 fprintf(stderr
, "_swrast_Point\n");
431 _swrast_print_vertex( ctx
, v0
);
433 SWRAST_CONTEXT(ctx
)->Point( ctx
, v0
);
437 _swrast_InvalidateState( GLcontext
*ctx
, GLuint new_state
)
440 fprintf(stderr
, "_swrast_InvalidateState\n");
442 SWRAST_CONTEXT(ctx
)->InvalidateState( ctx
, new_state
);
446 _swrast_ResetLineStipple( GLcontext
*ctx
)
449 fprintf(stderr
, "_swrast_ResetLineStipple\n");
451 SWRAST_CONTEXT(ctx
)->StippleCounter
= 0;
455 _swrast_allow_vertex_fog( GLcontext
*ctx
, GLboolean value
)
458 fprintf(stderr
, "_swrast_allow_vertex_fog %d\n", value
);
460 SWRAST_CONTEXT(ctx
)->InvalidateState( ctx
, _NEW_HINT
);
461 SWRAST_CONTEXT(ctx
)->AllowVertexFog
= value
;
465 _swrast_allow_pixel_fog( GLcontext
*ctx
, GLboolean value
)
468 fprintf(stderr
, "_swrast_allow_pixel_fog %d\n", value
);
470 SWRAST_CONTEXT(ctx
)->InvalidateState( ctx
, _NEW_HINT
);
471 SWRAST_CONTEXT(ctx
)->AllowPixelFog
= value
;
476 _swrast_CreateContext( GLcontext
*ctx
)
479 SWcontext
*swrast
= (SWcontext
*)CALLOC(sizeof(SWcontext
));
482 fprintf(stderr
, "_swrast_CreateContext\n");
488 swrast
->NewState
= ~0;
490 swrast
->choose_point
= _swrast_choose_point
;
491 swrast
->choose_line
= _swrast_choose_line
;
492 swrast
->choose_triangle
= _swrast_choose_triangle
;
494 swrast
->invalidate_point
= _SWRAST_NEW_POINT
;
495 swrast
->invalidate_line
= _SWRAST_NEW_LINE
;
496 swrast
->invalidate_triangle
= _SWRAST_NEW_TRIANGLE
;
498 swrast
->Point
= _swrast_validate_point
;
499 swrast
->Line
= _swrast_validate_line
;
500 swrast
->Triangle
= _swrast_validate_triangle
;
501 swrast
->InvalidateState
= _swrast_sleep
;
502 swrast
->BlendFunc
= _swrast_validate_blend_func
;
504 swrast
->AllowVertexFog
= GL_TRUE
;
505 swrast
->AllowPixelFog
= GL_TRUE
;
507 /* Optimized Accum buffer */
508 swrast
->_IntegerAccumMode
= GL_TRUE
;
509 swrast
->_IntegerAccumScaler
= 0.0;
511 for (i
= 0 ; i
< MAX_TEXTURE_UNITS
; i
++)
512 swrast
->TextureSample
[i
] = _swrast_validate_texture_sample
;
514 swrast
->span
= (struct sw_span
*) MALLOC(sizeof(struct sw_span
));
520 assert(ctx
->Const
.MaxTextureUnits
> 0);
521 assert(ctx
->Const
.MaxTextureUnits
<= MAX_TEXTURE_UNITS
);
523 swrast
->TexelBuffer
= (GLchan
*) MALLOC(ctx
->Const
.MaxTextureUnits
*
524 MAX_WIDTH
* 4 * sizeof(GLchan
));
525 if (!swrast
->TexelBuffer
) {
531 ctx
->swrast_context
= swrast
;
537 _swrast_DestroyContext( GLcontext
*ctx
)
539 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
542 fprintf(stderr
, "_swrast_DestroyContext\n");
545 FREE( swrast
->span
);
546 FREE( swrast
->TexelBuffer
);
549 ctx
->swrast_context
= 0;
553 struct swrast_device_driver
*
554 _swrast_GetDeviceDriverReference( GLcontext
*ctx
)
556 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
557 return &swrast
->Driver
;
560 #define SWRAST_DEBUG_VERTICES 0
563 _swrast_print_vertex( GLcontext
*ctx
, const SWvertex
*v
)
567 if (SWRAST_DEBUG_VERTICES
) {
568 fprintf(stderr
, "win %f %f %f %f\n",
569 v
->win
[0], v
->win
[1], v
->win
[2], v
->win
[3]);
571 for (i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++)
572 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
)
573 fprintf(stderr
, "texcoord[%d] %f %f %f %f\n", i
,
574 v
->texcoord
[i
][0], v
->texcoord
[i
][1],
575 v
->texcoord
[i
][2], v
->texcoord
[i
][3]);
577 #if CHAN_TYPE == GL_FLOAT
578 fprintf(stderr
, "color %f %f %f %f\n",
579 v
->color
[0], v
->color
[1], v
->color
[2], v
->color
[3]);
580 fprintf(stderr
, "spec %f %f %f %f\n",
581 v
->specular
[0], v
->specular
[1], v
->specular
[2], v
->specular
[3]);
583 fprintf(stderr
, "color %d %d %d %d\n",
584 v
->color
[0], v
->color
[1], v
->color
[2], v
->color
[3]);
585 fprintf(stderr
, "spec %d %d %d %d\n",
586 v
->specular
[0], v
->specular
[1], v
->specular
[2], v
->specular
[3]);
588 fprintf(stderr
, "fog %f\n", v
->fog
);
589 fprintf(stderr
, "index %d\n", v
->index
);
590 fprintf(stderr
, "pointsize %f\n", v
->pointSize
);
591 fprintf(stderr
, "\n");
597 _swrast_flush( GLcontext
*ctx
)