s_context.c revision 1e1aac034c986a08248861363c0baa27dc2ae2d5
1/* $Id: s_context.c,v 1.4 2000/11/13 20:02:57 keithw Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 3.5 6 * 7 * Copyright (C) 1999 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 "types.h" 32#include "mem.h" 33 34#include "s_pb.h" 35#include "s_points.h" 36#include "s_lines.h" 37#include "s_triangle.h" 38#include "s_quads.h" 39#include "s_blend.h" 40#include "s_context.h" 41#include "s_texture.h" 42 43 44 45 46 47/* 48 * Recompute the value of swrast->_RasterMask, etc. according to 49 * the current context. 50 */ 51static void 52_swrast_update_rasterflags( GLcontext *ctx ) 53{ 54 GLuint RasterMask = 0; 55 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.RGBAflag) { 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; 67 } 68 else { 69 if (ctx->Color.IndexMask != 0xffffffff) RasterMask |= MASKING_BIT; 70 if (ctx->Color.IndexLogicOpEnabled) RasterMask |= LOGIC_OP_BIT; 71 } 72 73 if (ctx->DrawBuffer->UseSoftwareAlphaBuffers 74 && ctx->Color.ColorMask[ACOMP] 75 && ctx->Color.DrawBuffer != GL_NONE) 76 RasterMask |= ALPHABUF_BIT; 77 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; 83 } 84 85 if (ctx->Depth.OcclusionTest) 86 RasterMask |= OCCLUSION_BIT; 87 88 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. 92 */ 93 if (ctx->Color.MultiDrawBuffer) { 94 RasterMask |= MULTI_DRAW_BIT; 95 } 96 else if (ctx->Color.DrawBuffer==GL_NONE) { 97 RasterMask |= MULTI_DRAW_BIT; 98 } 99 else if (ctx->Visual.RGBAflag && *((GLuint *) ctx->Color.ColorMask) == 0) { 100 RasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */ 101 } 102 else if (!ctx->Visual.RGBAflag && ctx->Color.IndexMask==0) { 103 RasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */ 104 } 105 106 if ( ctx->Viewport.X<0 107 || ctx->Viewport.X + ctx->Viewport.Width > ctx->DrawBuffer->Width 108 || ctx->Viewport.Y<0 109 || ctx->Viewport.Y + ctx->Viewport.Height > ctx->DrawBuffer->Height) { 110 RasterMask |= WINCLIP_BIT; 111 } 112 113 SWRAST_CONTEXT(ctx)->_RasterMask = RasterMask; 114} 115 116 117static void 118_swrast_update_polygon( GLcontext *ctx ) 119{ 120 GLfloat backface_sign = 1; 121 122 if (ctx->Polygon.CullFlag) { 123 backface_sign = 1; 124 switch(ctx->Polygon.CullFaceMode) { 125 case GL_BACK: 126 if(ctx->Polygon.FrontFace==GL_CCW) 127 backface_sign = -1; 128 break; 129 case GL_FRONT: 130 if(ctx->Polygon.FrontFace!=GL_CCW) 131 backface_sign = -1; 132 break; 133 default: 134 case GL_FRONT_AND_BACK: 135 backface_sign = 0; 136 break; 137 } 138 } 139 else { 140 backface_sign = 0; 141 } 142 143 SWRAST_CONTEXT(ctx)->_backface_sign = backface_sign; 144} 145 146 147static void 148_swrast_update_hint( GLcontext *ctx ) 149{ 150 SWcontext *swrast = SWRAST_CONTEXT(ctx); 151 swrast->_PreferPixelFog = (!swrast->AllowVertexFog || 152 (ctx->Hint.Fog == GL_NICEST && 153 swrast->AllowPixelFog)); 154} 155 156#define _SWRAST_NEW_TRIANGLE (_NEW_RENDERMODE| \ 157 _NEW_POLYGON| \ 158 _NEW_DEPTH| \ 159 _NEW_STENCIL| \ 160 _NEW_COLOR| \ 161 _NEW_TEXTURE| \ 162 _NEW_HINT| \ 163 _SWRAST_NEW_RASTERMASK| \ 164 _NEW_LIGHT| \ 165 _NEW_FOG) 166 167#define _SWRAST_NEW_LINE (_NEW_RENDERMODE| \ 168 _NEW_LINE| \ 169 _NEW_TEXTURE| \ 170 _NEW_LIGHT| \ 171 _NEW_FOG| \ 172 _NEW_DEPTH) 173 174#define _SWRAST_NEW_POINT (_NEW_RENDERMODE | \ 175 _NEW_POINT | \ 176 _NEW_TEXTURE | \ 177 _NEW_LIGHT | \ 178 _NEW_FOG) 179 180#define _SWRAST_NEW_QUAD 0 181 182#define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE 183 184#define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR 185 186 187 188/* Stub for swrast->Triangle to select a true triangle function 189 * after a state change. 190 */ 191static void 192_swrast_validate_quad( GLcontext *ctx, 193 SWvertex *v0, SWvertex *v1, SWvertex *v2, SWvertex *v3 ) 194{ 195 SWcontext *swrast = SWRAST_CONTEXT(ctx); 196 197 _swrast_validate_derived( ctx ); 198 swrast->choose_quad( ctx ); 199 200 swrast->Quad( ctx, v0, v1, v2, v3 ); 201} 202 203static void 204_swrast_validate_triangle( GLcontext *ctx, 205 SWvertex *v0, SWvertex *v1, SWvertex *v2 ) 206{ 207 SWcontext *swrast = SWRAST_CONTEXT(ctx); 208 209 _swrast_validate_derived( ctx ); 210 swrast->choose_triangle( ctx ); 211 212 swrast->Triangle( ctx, v0, v1, v2 ); 213} 214 215static void 216_swrast_validate_line( GLcontext *ctx, SWvertex *v0, SWvertex *v1 ) 217{ 218 SWcontext *swrast = SWRAST_CONTEXT(ctx); 219 220 _swrast_validate_derived( ctx ); 221 swrast->choose_line( ctx ); 222 223 swrast->Line( ctx, v0, v1 ); 224} 225 226static void 227_swrast_validate_point( GLcontext *ctx, SWvertex *v0 ) 228{ 229 SWcontext *swrast = SWRAST_CONTEXT(ctx); 230 231 _swrast_validate_derived( ctx ); 232 swrast->choose_point( ctx ); 233 234 swrast->Point( ctx, v0 ); 235} 236 237static void 238_swrast_validate_blend_func( GLcontext *ctx, GLuint n, 239 const GLubyte mask[], 240 GLchan src[][4], 241 CONST GLchan dst[][4] ) 242{ 243 SWcontext *swrast = SWRAST_CONTEXT(ctx); 244 245 _swrast_validate_derived( ctx ); 246 _swrast_choose_blend_func( ctx ); 247 248 swrast->BlendFunc( ctx, n, mask, src, dst ); 249} 250 251 252static void 253_swrast_validate_texture_sample( GLcontext *ctx, GLuint texUnit, 254 const struct gl_texture_object *tObj, 255 GLuint n, 256 const GLfloat s[], const GLfloat t[], 257 const GLfloat u[], const GLfloat lambda[], 258 GLchan rgba[][4] ) 259{ 260 SWcontext *swrast = SWRAST_CONTEXT(ctx); 261 262 _swrast_validate_derived( ctx ); 263 _swrast_choose_texture_sample_func( ctx, texUnit, tObj ); 264 265 swrast->TextureSample[texUnit]( ctx, texUnit, tObj, n, s, t, u, 266 lambda, rgba ); 267} 268 269 270static void 271_swrast_sleep( GLcontext *ctx, GLuint new_state ) 272{ 273} 274 275 276static void 277_swrast_invalidate_state( GLcontext *ctx, GLuint new_state ) 278{ 279 SWcontext *swrast = SWRAST_CONTEXT(ctx); 280 GLuint i; 281 282 swrast->NewState |= new_state; 283 284 /* After 10 statechanges without any swrast functions being called, 285 * put the module to sleep. 286 */ 287 if (++swrast->StateChanges > 10) { 288 swrast->InvalidateState = _swrast_sleep; 289 swrast->NewState = ~0; 290 new_state = ~0; 291 } 292 293 if (new_state & swrast->invalidate_triangle) 294 swrast->Triangle = _swrast_validate_triangle; 295 296 if (new_state & swrast->invalidate_line) 297 swrast->Line = _swrast_validate_line; 298 299 if (new_state & swrast->invalidate_point) 300 swrast->Point = _swrast_validate_point; 301 302 if (new_state & swrast->invalidate_quad) 303 swrast->Quad = _swrast_validate_quad; 304 305 if (new_state & _SWRAST_NEW_BLEND_FUNC) 306 swrast->BlendFunc = _swrast_validate_blend_func; 307 308 if (new_state & _SWRAST_NEW_TEXTURE_SAMPLE_FUNC) 309 for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) 310 swrast->TextureSample[i] = _swrast_validate_texture_sample; 311} 312 313 314 315void 316_swrast_validate_derived( GLcontext *ctx ) 317{ 318 SWcontext *swrast = SWRAST_CONTEXT(ctx); 319 320 if (swrast->NewState) 321 { 322 if (swrast->NewState & _SWRAST_NEW_RASTERMASK) 323 _swrast_update_rasterflags( ctx ); 324 325 if (swrast->NewState & _NEW_TEXTURE) 326 swrast->_MultiTextureEnabled = (ctx->Texture._ReallyEnabled & 327 ~ENABLE_TEX0); 328 329 if (swrast->NewState & _NEW_POLYGON) 330 _swrast_update_polygon( ctx ); 331 332 if (swrast->NewState & _NEW_HINT) 333 _swrast_update_hint( ctx ); 334 335 swrast->NewState = 0; 336 swrast->StateChanges = 0; 337 swrast->InvalidateState = _swrast_invalidate_state; 338 } 339} 340 341 342 343/* Public entrypoints: See also s_accum.c, s_bitmap.c, etc. 344 */ 345void 346_swrast_Quad( GLcontext *ctx, 347 SWvertex *v0, SWvertex *v1, SWvertex *v2, SWvertex *v3 ) 348{ 349 SWRAST_CONTEXT(ctx)->Quad( ctx, v0, v1, v2, v3 ); 350} 351 352void 353_swrast_Triangle( GLcontext *ctx, SWvertex *v0, SWvertex *v1, SWvertex *v2 ) 354{ 355 SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 ); 356} 357 358void 359_swrast_Line( GLcontext *ctx, SWvertex *v0, SWvertex *v1 ) 360{ 361 SWRAST_CONTEXT(ctx)->Line( ctx, v0, v1 ); 362} 363 364void 365_swrast_Point( GLcontext *ctx, SWvertex *v0 ) 366{ 367 SWRAST_CONTEXT(ctx)->Point( ctx, v0 ); 368} 369 370void 371_swrast_InvalidateState( GLcontext *ctx, GLuint new_state ) 372{ 373 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, new_state ); 374} 375 376 377GLuint * 378_swrast_get_stipple_counter_ref( GLcontext *ctx ) 379{ 380 return &SWRAST_CONTEXT(ctx)->StippleCounter; 381} 382 383void 384_swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value ) 385{ 386 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); 387 SWRAST_CONTEXT(ctx)->AllowVertexFog = value; 388} 389 390void 391_swrast_allow_pixel_fog( GLcontext *ctx, GLboolean value ) 392{ 393 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); 394 SWRAST_CONTEXT(ctx)->AllowPixelFog = value; 395} 396 397 398GLboolean 399_swrast_CreateContext( GLcontext *ctx ) 400{ 401 GLuint i; 402 SWcontext *swrast = (SWcontext *)CALLOC(sizeof(SWcontext)); 403 if (!swrast) 404 return GL_FALSE; 405 406 swrast->PB = gl_alloc_pb(); 407 if (!swrast->PB) { 408 FREE(swrast); 409 return GL_FALSE; 410 } 411 412 swrast->NewState = ~0; 413 414 swrast->choose_point = _swrast_choose_point; 415 swrast->choose_line = _swrast_choose_line; 416 swrast->choose_triangle = _swrast_choose_triangle; 417 swrast->choose_quad = _swrast_choose_quad; 418 419 swrast->invalidate_point = _SWRAST_NEW_POINT; 420 swrast->invalidate_line = _SWRAST_NEW_LINE; 421 swrast->invalidate_triangle = _SWRAST_NEW_TRIANGLE; 422 swrast->invalidate_quad = _SWRAST_NEW_QUAD; 423 424 swrast->Point = _swrast_validate_point; 425 swrast->Line = _swrast_validate_line; 426 swrast->Triangle = _swrast_validate_triangle; 427 swrast->Quad = _swrast_validate_quad; 428 swrast->InvalidateState = _swrast_sleep; 429 swrast->BlendFunc = _swrast_validate_blend_func; 430 431 swrast->AllowVertexFog = GL_TRUE; 432 swrast->AllowPixelFog = GL_TRUE; 433 434 /* Optimized Accum buffer */ 435 swrast->_IntegerAccumMode = GL_TRUE; 436 swrast->_IntegerAccumScaler = 0.0; 437 438 439 for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) 440 swrast->TextureSample[i] = _swrast_validate_texture_sample; 441 442 ctx->swrast_context = swrast; 443 return GL_TRUE; 444} 445 446void 447_swrast_DestroyContext( GLcontext *ctx ) 448{ 449 SWcontext *swrast = SWRAST_CONTEXT(ctx); 450 451 FREE( swrast->PB ); 452 FREE( swrast ); 453 454 ctx->swrast_context = 0; 455} 456 457