s_context.c revision 0bf5dbe002a64e198f55724cc1542602c012490f
1/* 2 * Mesa 3-D graphics library 3 * Version: 6.5.1 4 * 5 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Keith Whitwell <keith@tungstengraphics.com> 26 * Brian Paul 27 */ 28 29#include "imports.h" 30#include "bufferobj.h" 31#include "context.h" 32#include "colormac.h" 33#include "mtypes.h" 34#include "prog_statevars.h" 35#include "teximage.h" 36#include "swrast.h" 37#include "s_blend.h" 38#include "s_context.h" 39#include "s_lines.h" 40#include "s_points.h" 41#include "s_span.h" 42#include "s_triangle.h" 43#include "s_texfilter.h" 44 45 46/** 47 * Recompute the value of swrast->_RasterMask, etc. according to 48 * the current context. The _RasterMask field can be easily tested by 49 * drivers to determine certain basic GL state (does the primitive need 50 * stenciling, logic-op, fog, etc?). 51 */ 52static void 53_swrast_update_rasterflags( GLcontext *ctx ) 54{ 55 SWcontext *swrast = SWRAST_CONTEXT(ctx); 56 GLbitfield rasterMask = 0; 57 58 if (ctx->Color.AlphaEnabled) rasterMask |= ALPHATEST_BIT; 59 if (ctx->Color.BlendEnabled) rasterMask |= BLEND_BIT; 60 if (ctx->Depth.Test) rasterMask |= DEPTH_BIT; 61 if (swrast->_FogEnabled) rasterMask |= FOG_BIT; 62 if (ctx->Scissor.Enabled) rasterMask |= CLIP_BIT; 63 if (ctx->Stencil.Enabled) rasterMask |= STENCIL_BIT; 64 if (ctx->Visual.rgbMode) { 65 const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); 66 if (colorMask != 0xffffffff) rasterMask |= MASKING_BIT; 67 if (ctx->Color._LogicOpEnabled) rasterMask |= LOGIC_OP_BIT; 68 if (ctx->Texture._EnabledUnits) rasterMask |= TEXTURE_BIT; 69 } 70 else { 71 if (ctx->Color.IndexMask != 0xffffffff) rasterMask |= MASKING_BIT; 72 if (ctx->Color.IndexLogicOpEnabled) rasterMask |= LOGIC_OP_BIT; 73 } 74 75 if ( ctx->Viewport.X < 0 76 || ctx->Viewport.X + ctx->Viewport.Width > (GLint) ctx->DrawBuffer->Width 77 || ctx->Viewport.Y < 0 78 || ctx->Viewport.Y + ctx->Viewport.Height > (GLint) ctx->DrawBuffer->Height) { 79 rasterMask |= CLIP_BIT; 80 } 81 82 if (ctx->Query.CurrentOcclusionObject) 83 rasterMask |= OCCLUSION_BIT; 84 85 86 /* If we're not drawing to exactly one color buffer set the 87 * MULTI_DRAW_BIT flag. Also set it if we're drawing to no 88 * buffers or the RGBA or CI mask disables all writes. 89 */ 90 if (ctx->DrawBuffer->_NumColorDrawBuffers[0] != 1) { 91 /* more than one color buffer designated for writing (or zero buffers) */ 92 rasterMask |= MULTI_DRAW_BIT; 93 } 94 else if (ctx->Visual.rgbMode && *((GLuint *) ctx->Color.ColorMask) == 0) { 95 rasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */ 96 } 97 else if (!ctx->Visual.rgbMode && ctx->Color.IndexMask==0) { 98 rasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */ 99 } 100 101 if (ctx->FragmentProgram._Current) { 102 rasterMask |= FRAGPROG_BIT; 103 } 104 105 if (ctx->Shader._FragmentShaderPresent) { 106 rasterMask |= FRAGPROG_BIT; 107 } 108 109 if (ctx->ATIFragmentShader._Enabled) { 110 rasterMask |= ATIFRAGSHADER_BIT; 111 } 112 113#if CHAN_TYPE == GL_FLOAT 114 if (ctx->Color.ClampFragmentColor == GL_TRUE) { 115 rasterMask |= CLAMPING_BIT; 116 } 117#endif 118 119 SWRAST_CONTEXT(ctx)->_RasterMask = rasterMask; 120} 121 122 123/** 124 * Examine polycon culls tate to compute the _BackfaceSign field. 125 * _BackfaceSign will be 0 if no culling, -1 if culling back-faces, 126 * and 1 if culling front-faces. The Polygon FrontFace state also 127 * factors in. 128 */ 129static void 130_swrast_update_polygon( GLcontext *ctx ) 131{ 132 GLfloat backface_sign = 1; 133 134 if (ctx->Polygon.CullFlag) { 135 backface_sign = 1; 136 switch(ctx->Polygon.CullFaceMode) { 137 case GL_BACK: 138 if(ctx->Polygon.FrontFace==GL_CCW) 139 backface_sign = -1; 140 break; 141 case GL_FRONT: 142 if(ctx->Polygon.FrontFace!=GL_CCW) 143 backface_sign = -1; 144 break; 145 default: 146 case GL_FRONT_AND_BACK: 147 backface_sign = 0; 148 break; 149 } 150 } 151 else { 152 backface_sign = 0; 153 } 154 155 SWRAST_CONTEXT(ctx)->_BackfaceSign = backface_sign; 156} 157 158 159/** 160 * Update the _PreferPixelFog field to indicate if we need to compute 161 * fog factors per-fragment. 162 */ 163static void 164_swrast_update_fog_hint( GLcontext *ctx ) 165{ 166 SWcontext *swrast = SWRAST_CONTEXT(ctx); 167 swrast->_PreferPixelFog = (!swrast->AllowVertexFog || 168 ctx->FragmentProgram._Current || 169 (ctx->Hint.Fog == GL_NICEST && 170 swrast->AllowPixelFog)); 171} 172 173 174 175/** 176 * Update the swrast->_AnyTextureCombine flag. 177 */ 178static void 179_swrast_update_texture_env( GLcontext *ctx ) 180{ 181 SWcontext *swrast = SWRAST_CONTEXT(ctx); 182 GLuint i; 183 swrast->_AnyTextureCombine = GL_FALSE; 184 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 185 if (ctx->Texture.Unit[i].EnvMode == GL_COMBINE_EXT || 186 ctx->Texture.Unit[i].EnvMode == GL_COMBINE4_NV) { 187 swrast->_AnyTextureCombine = GL_TRUE; 188 return; 189 } 190 } 191} 192 193 194/** 195 * Update swrast->_FogColor and swrast->_FogEnable values. 196 */ 197static void 198_swrast_update_fog_state( GLcontext *ctx ) 199{ 200 SWcontext *swrast = SWRAST_CONTEXT(ctx); 201 const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; 202 203 /* determine if fog is needed, and if so, which fog mode */ 204 swrast->_FogEnabled = GL_FALSE; 205 if (fp && fp->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { 206 if (fp->FogOption != GL_NONE) { 207 swrast->_FogEnabled = GL_TRUE; 208 swrast->_FogMode = fp->FogOption; 209 } 210 } 211 else if (ctx->Fog.Enabled) { 212 swrast->_FogEnabled = GL_TRUE; 213 swrast->_FogMode = ctx->Fog.Mode; 214 } 215} 216 217 218/** 219 * Update state for running fragment programs. Basically, load the 220 * program parameters with current state values. 221 */ 222static void 223_swrast_update_fragment_program(GLcontext *ctx, GLbitfield newState) 224{ 225 const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; 226 if (fp) { 227#if 0 228 /* XXX Need a way to trigger the initial loading of parameters 229 * even when there's no recent state changes. 230 */ 231 if (fp->Base.Parameters->StateFlags & newState) 232#endif 233 _mesa_load_state_parameters(ctx, fp->Base.Parameters); 234 } 235} 236 237 238 239#define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK | \ 240 _NEW_TEXTURE | \ 241 _NEW_HINT | \ 242 _NEW_POLYGON ) 243 244/* State referenced by _swrast_choose_triangle, _swrast_choose_line. 245 */ 246#define _SWRAST_NEW_TRIANGLE (_SWRAST_NEW_DERIVED | \ 247 _NEW_RENDERMODE| \ 248 _NEW_POLYGON| \ 249 _NEW_DEPTH| \ 250 _NEW_STENCIL| \ 251 _NEW_COLOR| \ 252 _NEW_TEXTURE| \ 253 _SWRAST_NEW_RASTERMASK| \ 254 _NEW_LIGHT| \ 255 _NEW_FOG | \ 256 _DD_NEW_SEPARATE_SPECULAR) 257 258#define _SWRAST_NEW_LINE (_SWRAST_NEW_DERIVED | \ 259 _NEW_RENDERMODE| \ 260 _NEW_LINE| \ 261 _NEW_TEXTURE| \ 262 _NEW_LIGHT| \ 263 _NEW_FOG| \ 264 _NEW_DEPTH | \ 265 _DD_NEW_SEPARATE_SPECULAR) 266 267#define _SWRAST_NEW_POINT (_SWRAST_NEW_DERIVED | \ 268 _NEW_RENDERMODE | \ 269 _NEW_POINT | \ 270 _NEW_TEXTURE | \ 271 _NEW_LIGHT | \ 272 _NEW_FOG | \ 273 _DD_NEW_SEPARATE_SPECULAR) 274 275#define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE 276 277#define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE 278 279#define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR 280 281 282 283/** 284 * Stub for swrast->Triangle to select a true triangle function 285 * after a state change. 286 */ 287static void 288_swrast_validate_triangle( GLcontext *ctx, 289 const SWvertex *v0, 290 const SWvertex *v1, 291 const SWvertex *v2 ) 292{ 293 SWcontext *swrast = SWRAST_CONTEXT(ctx); 294 295 _swrast_validate_derived( ctx ); 296 swrast->choose_triangle( ctx ); 297 ASSERT(swrast->Triangle); 298 299 if (ctx->Texture._EnabledUnits == 0 300 && NEED_SECONDARY_COLOR(ctx) 301 && !ctx->FragmentProgram._Current) { 302 /* separate specular color, but no texture */ 303 swrast->SpecTriangle = swrast->Triangle; 304 swrast->Triangle = _swrast_add_spec_terms_triangle; 305 } 306 307 swrast->Triangle( ctx, v0, v1, v2 ); 308} 309 310/** 311 * Called via swrast->Line. Examine current GL state and choose a software 312 * line routine. Then call it. 313 */ 314static void 315_swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) 316{ 317 SWcontext *swrast = SWRAST_CONTEXT(ctx); 318 319 _swrast_validate_derived( ctx ); 320 swrast->choose_line( ctx ); 321 ASSERT(swrast->Line); 322 323 if (ctx->Texture._EnabledUnits == 0 324 && NEED_SECONDARY_COLOR(ctx) 325 && !ctx->FragmentProgram._Current) { 326 swrast->SpecLine = swrast->Line; 327 swrast->Line = _swrast_add_spec_terms_line; 328 } 329 330 331 swrast->Line( ctx, v0, v1 ); 332} 333 334/** 335 * Called via swrast->Point. Examine current GL state and choose a software 336 * point routine. Then call it. 337 */ 338static void 339_swrast_validate_point( GLcontext *ctx, const SWvertex *v0 ) 340{ 341 SWcontext *swrast = SWRAST_CONTEXT(ctx); 342 343 _swrast_validate_derived( ctx ); 344 swrast->choose_point( ctx ); 345 346 if (ctx->Texture._EnabledUnits == 0 347 && NEED_SECONDARY_COLOR(ctx) 348 && !ctx->FragmentProgram._Current) { 349 swrast->SpecPoint = swrast->Point; 350 swrast->Point = _swrast_add_spec_terms_point; 351 } 352 353 swrast->Point( ctx, v0 ); 354} 355 356 357/** 358 * Called via swrast->BlendFunc. Examine GL state to choose a blending 359 * function, then call it. 360 */ 361static void _ASMAPI 362_swrast_validate_blend_func(GLcontext *ctx, GLuint n, const GLubyte mask[], 363 GLvoid *src, const GLvoid *dst, 364 GLenum chanType ) 365{ 366 SWcontext *swrast = SWRAST_CONTEXT(ctx); 367 368 _swrast_validate_derived( ctx ); /* why is this needed? */ 369 _swrast_choose_blend_func( ctx, chanType ); 370 371 swrast->BlendFunc( ctx, n, mask, src, dst, chanType ); 372} 373 374 375/** 376 * Make sure we have texture image data for all the textures we may need 377 * for subsequent rendering. 378 */ 379static void 380_swrast_validate_texture_images(GLcontext *ctx) 381{ 382 SWcontext *swrast = SWRAST_CONTEXT(ctx); 383 GLuint u; 384 385 if (!swrast->ValidateTextureImage || !ctx->Texture._EnabledUnits) { 386 /* no textures enabled, or no way to validate images! */ 387 return; 388 } 389 390 for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) { 391 if (ctx->Texture.Unit[u]._ReallyEnabled) { 392 struct gl_texture_object *texObj = ctx->Texture.Unit[u]._Current; 393 ASSERT(texObj); 394 if (texObj) { 395 GLuint numFaces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 396 GLuint face; 397 for (face = 0; face < numFaces; face++) { 398 GLuint lvl; 399 for (lvl = texObj->BaseLevel; lvl <= texObj->_MaxLevel; lvl++) { 400 struct gl_texture_image *texImg = texObj->Image[face][lvl]; 401 if (texImg && !texImg->Data) { 402 swrast->ValidateTextureImage(ctx, texObj, face, lvl); 403 ASSERT(texObj->Image[face][lvl]->Data); 404 } 405 } 406 } 407 } 408 } 409 } 410} 411 412 413/** 414 * Free the texture image data attached to all currently enabled 415 * textures. Meant to be called by device drivers when transitioning 416 * from software to hardware rendering. 417 */ 418void 419_swrast_eject_texture_images(GLcontext *ctx) 420{ 421 GLuint u; 422 423 if (!ctx->Texture._EnabledUnits) { 424 /* no textures enabled */ 425 return; 426 } 427 428 for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) { 429 if (ctx->Texture.Unit[u]._ReallyEnabled) { 430 struct gl_texture_object *texObj = ctx->Texture.Unit[u]._Current; 431 ASSERT(texObj); 432 if (texObj) { 433 GLuint numFaces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 434 GLuint face; 435 for (face = 0; face < numFaces; face++) { 436 GLuint lvl; 437 for (lvl = texObj->BaseLevel; lvl <= texObj->_MaxLevel; lvl++) { 438 struct gl_texture_image *texImg = texObj->Image[face][lvl]; 439 if (texImg && texImg->Data) { 440 _mesa_free_texmemory(texImg->Data); 441 texImg->Data = NULL; 442 } 443 } 444 } 445 } 446 } 447 } 448} 449 450 451 452static void 453_swrast_sleep( GLcontext *ctx, GLbitfield new_state ) 454{ 455 (void) ctx; (void) new_state; 456} 457 458 459static void 460_swrast_invalidate_state( GLcontext *ctx, GLbitfield new_state ) 461{ 462 SWcontext *swrast = SWRAST_CONTEXT(ctx); 463 GLuint i; 464 465 swrast->NewState |= new_state; 466 467 /* After 10 statechanges without any swrast functions being called, 468 * put the module to sleep. 469 */ 470 if (++swrast->StateChanges > 10) { 471 swrast->InvalidateState = _swrast_sleep; 472 swrast->NewState = ~0; 473 new_state = ~0; 474 } 475 476 if (new_state & swrast->InvalidateTriangleMask) 477 swrast->Triangle = _swrast_validate_triangle; 478 479 if (new_state & swrast->InvalidateLineMask) 480 swrast->Line = _swrast_validate_line; 481 482 if (new_state & swrast->InvalidatePointMask) 483 swrast->Point = _swrast_validate_point; 484 485 if (new_state & _SWRAST_NEW_BLEND_FUNC) 486 swrast->BlendFunc = _swrast_validate_blend_func; 487 488 if (new_state & _SWRAST_NEW_TEXTURE_SAMPLE_FUNC) 489 for (i = 0 ; i < ctx->Const.MaxTextureImageUnits ; i++) 490 swrast->TextureSample[i] = NULL; 491} 492 493 494static void 495_swrast_update_texture_samplers(GLcontext *ctx) 496{ 497 SWcontext *swrast = SWRAST_CONTEXT(ctx); 498 GLuint u; 499 500 for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) { 501 const struct gl_texture_object *tObj = ctx->Texture.Unit[u]._Current; 502 if (tObj) 503 swrast->TextureSample[u] = 504 _swrast_choose_texture_sample_func(ctx, tObj); 505 } 506} 507 508 509void 510_swrast_validate_derived( GLcontext *ctx ) 511{ 512 SWcontext *swrast = SWRAST_CONTEXT(ctx); 513 514 if (swrast->NewState) { 515 if (swrast->NewState & _NEW_POLYGON) 516 _swrast_update_polygon( ctx ); 517 518 if (swrast->NewState & (_NEW_HINT | _NEW_PROGRAM)) 519 _swrast_update_fog_hint( ctx ); 520 521 if (swrast->NewState & _SWRAST_NEW_TEXTURE_ENV_MODE) 522 _swrast_update_texture_env( ctx ); 523 524 if (swrast->NewState & (_NEW_FOG | _NEW_PROGRAM)) 525 _swrast_update_fog_state( ctx ); 526 527 if (swrast->NewState & (_NEW_MODELVIEW | 528 _NEW_PROJECTION | 529 _NEW_TEXTURE_MATRIX | 530 _NEW_FOG | 531 _NEW_LIGHT | 532 _NEW_LINE | 533 _NEW_TEXTURE | 534 _NEW_TRANSFORM | 535 _NEW_POINT | 536 _NEW_VIEWPORT | 537 _NEW_PROGRAM)) 538 _swrast_update_fragment_program( ctx, swrast->NewState ); 539 540 if (swrast->NewState & _NEW_TEXTURE) 541 _swrast_update_texture_samplers( ctx ); 542 543 if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM)) 544 _swrast_validate_texture_images( ctx ); 545 546 if (swrast->NewState & _SWRAST_NEW_RASTERMASK) 547 _swrast_update_rasterflags( ctx ); 548 549 swrast->NewState = 0; 550 swrast->StateChanges = 0; 551 swrast->InvalidateState = _swrast_invalidate_state; 552 } 553} 554 555#define SWRAST_DEBUG 0 556 557/* Public entrypoints: See also s_accum.c, s_bitmap.c, etc. 558 */ 559void 560_swrast_Quad( GLcontext *ctx, 561 const SWvertex *v0, const SWvertex *v1, 562 const SWvertex *v2, const SWvertex *v3 ) 563{ 564 if (SWRAST_DEBUG) { 565 _mesa_debug(ctx, "_swrast_Quad\n"); 566 _swrast_print_vertex( ctx, v0 ); 567 _swrast_print_vertex( ctx, v1 ); 568 _swrast_print_vertex( ctx, v2 ); 569 _swrast_print_vertex( ctx, v3 ); 570 } 571 SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v3 ); 572 SWRAST_CONTEXT(ctx)->Triangle( ctx, v1, v2, v3 ); 573} 574 575void 576_swrast_Triangle( GLcontext *ctx, const SWvertex *v0, 577 const SWvertex *v1, const SWvertex *v2 ) 578{ 579 if (SWRAST_DEBUG) { 580 _mesa_debug(ctx, "_swrast_Triangle\n"); 581 _swrast_print_vertex( ctx, v0 ); 582 _swrast_print_vertex( ctx, v1 ); 583 _swrast_print_vertex( ctx, v2 ); 584 } 585 SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 ); 586} 587 588void 589_swrast_Line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) 590{ 591 if (SWRAST_DEBUG) { 592 _mesa_debug(ctx, "_swrast_Line\n"); 593 _swrast_print_vertex( ctx, v0 ); 594 _swrast_print_vertex( ctx, v1 ); 595 } 596 SWRAST_CONTEXT(ctx)->Line( ctx, v0, v1 ); 597} 598 599void 600_swrast_Point( GLcontext *ctx, const SWvertex *v0 ) 601{ 602 if (SWRAST_DEBUG) { 603 _mesa_debug(ctx, "_swrast_Point\n"); 604 _swrast_print_vertex( ctx, v0 ); 605 } 606 SWRAST_CONTEXT(ctx)->Point( ctx, v0 ); 607} 608 609void 610_swrast_InvalidateState( GLcontext *ctx, GLbitfield new_state ) 611{ 612 if (SWRAST_DEBUG) { 613 _mesa_debug(ctx, "_swrast_InvalidateState\n"); 614 } 615 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, new_state ); 616} 617 618void 619_swrast_ResetLineStipple( GLcontext *ctx ) 620{ 621 if (SWRAST_DEBUG) { 622 _mesa_debug(ctx, "_swrast_ResetLineStipple\n"); 623 } 624 SWRAST_CONTEXT(ctx)->StippleCounter = 0; 625} 626 627void 628_swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value ) 629{ 630 if (SWRAST_DEBUG) { 631 _mesa_debug(ctx, "_swrast_allow_vertex_fog %d\n", value); 632 } 633 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); 634 SWRAST_CONTEXT(ctx)->AllowVertexFog = value; 635} 636 637void 638_swrast_allow_pixel_fog( GLcontext *ctx, GLboolean value ) 639{ 640 if (SWRAST_DEBUG) { 641 _mesa_debug(ctx, "_swrast_allow_pixel_fog %d\n", value); 642 } 643 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); 644 SWRAST_CONTEXT(ctx)->AllowPixelFog = value; 645} 646 647 648GLboolean 649_swrast_CreateContext( GLcontext *ctx ) 650{ 651 GLuint i; 652 SWcontext *swrast = (SWcontext *)CALLOC(sizeof(SWcontext)); 653 654 if (SWRAST_DEBUG) { 655 _mesa_debug(ctx, "_swrast_CreateContext\n"); 656 } 657 658 if (!swrast) 659 return GL_FALSE; 660 661 swrast->NewState = ~0; 662 663 swrast->choose_point = _swrast_choose_point; 664 swrast->choose_line = _swrast_choose_line; 665 swrast->choose_triangle = _swrast_choose_triangle; 666 667 swrast->InvalidatePointMask = _SWRAST_NEW_POINT; 668 swrast->InvalidateLineMask = _SWRAST_NEW_LINE; 669 swrast->InvalidateTriangleMask = _SWRAST_NEW_TRIANGLE; 670 671 swrast->Point = _swrast_validate_point; 672 swrast->Line = _swrast_validate_line; 673 swrast->Triangle = _swrast_validate_triangle; 674 swrast->InvalidateState = _swrast_sleep; 675 swrast->BlendFunc = _swrast_validate_blend_func; 676 677 swrast->AllowVertexFog = GL_TRUE; 678 swrast->AllowPixelFog = GL_TRUE; 679 680 /* Optimized Accum buffer */ 681 swrast->_IntegerAccumMode = GL_FALSE; 682 swrast->_IntegerAccumScaler = 0.0; 683 684 for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) 685 swrast->TextureSample[i] = NULL; 686 687 swrast->SpanArrays = MALLOC_STRUCT(sw_span_arrays); 688 if (!swrast->SpanArrays) { 689 FREE(swrast); 690 return GL_FALSE; 691 } 692 swrast->SpanArrays->ChanType = CHAN_TYPE; 693#if CHAN_TYPE == GL_UNSIGNED_BYTE 694 swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz1.rgba; 695 swrast->SpanArrays->spec = swrast->SpanArrays->color.sz1.spec; 696#elif CHAN_TYPE == GL_UNSIGNED_SHORT 697 swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz2.rgba; 698 swrast->SpanArrays->spec = swrast->SpanArrays->color.sz2.spec; 699#else 700 swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz4.rgba; 701 swrast->SpanArrays->spec = swrast->SpanArrays->color.sz4.spec; 702#endif 703 704 /* init point span buffer */ 705 swrast->PointSpan.primitive = GL_POINT; 706 swrast->PointSpan.start = 0; 707 swrast->PointSpan.end = 0; 708 swrast->PointSpan.facing = 0; 709 swrast->PointSpan.array = swrast->SpanArrays; 710 711 swrast->TexelBuffer = (GLchan *) MALLOC(ctx->Const.MaxTextureImageUnits * 712 MAX_WIDTH * 4 * sizeof(GLchan)); 713 if (!swrast->TexelBuffer) { 714 FREE(swrast->SpanArrays); 715 FREE(swrast); 716 return GL_FALSE; 717 } 718 719 ctx->swrast_context = swrast; 720 721 return GL_TRUE; 722} 723 724void 725_swrast_DestroyContext( GLcontext *ctx ) 726{ 727 SWcontext *swrast = SWRAST_CONTEXT(ctx); 728 729 if (SWRAST_DEBUG) { 730 _mesa_debug(ctx, "_swrast_DestroyContext\n"); 731 } 732 733 FREE( swrast->SpanArrays ); 734 FREE( swrast->TexelBuffer ); 735 FREE( swrast ); 736 737 ctx->swrast_context = 0; 738} 739 740 741struct swrast_device_driver * 742_swrast_GetDeviceDriverReference( GLcontext *ctx ) 743{ 744 SWcontext *swrast = SWRAST_CONTEXT(ctx); 745 return &swrast->Driver; 746} 747 748void 749_swrast_flush( GLcontext *ctx ) 750{ 751 SWcontext *swrast = SWRAST_CONTEXT(ctx); 752 /* flush any pending fragments from rendering points */ 753 if (swrast->PointSpan.end > 0) { 754 if (ctx->Visual.rgbMode) { 755 _swrast_write_rgba_span(ctx, &(swrast->PointSpan)); 756 } 757 else { 758 _swrast_write_index_span(ctx, &(swrast->PointSpan)); 759 } 760 swrast->PointSpan.end = 0; 761 } 762} 763 764void 765_swrast_render_primitive( GLcontext *ctx, GLenum prim ) 766{ 767 SWcontext *swrast = SWRAST_CONTEXT(ctx); 768 if (swrast->Primitive == GL_POINTS && prim != GL_POINTS) { 769 _swrast_flush(ctx); 770 } 771 swrast->Primitive = prim; 772} 773 774 775void 776_swrast_render_start( GLcontext *ctx ) 777{ 778 SWcontext *swrast = SWRAST_CONTEXT(ctx); 779 if (swrast->Driver.SpanRenderStart) 780 swrast->Driver.SpanRenderStart( ctx ); 781 swrast->PointSpan.end = 0; 782} 783 784void 785_swrast_render_finish( GLcontext *ctx ) 786{ 787 SWcontext *swrast = SWRAST_CONTEXT(ctx); 788 if (swrast->Driver.SpanRenderFinish) 789 swrast->Driver.SpanRenderFinish( ctx ); 790 791 _swrast_flush(ctx); 792} 793 794 795#define SWRAST_DEBUG_VERTICES 0 796 797void 798_swrast_print_vertex( GLcontext *ctx, const SWvertex *v ) 799{ 800 GLuint i; 801 802 if (SWRAST_DEBUG_VERTICES) { 803 _mesa_debug(ctx, "win %f %f %f %f\n", 804 v->win[0], v->win[1], v->win[2], v->win[3]); 805 806 for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) 807 if (ctx->Texture.Unit[i]._ReallyEnabled) 808 _mesa_debug(ctx, "texcoord[%d] %f %f %f %f\n", i, 809 v->texcoord[i][0], v->texcoord[i][1], 810 v->texcoord[i][2], v->texcoord[i][3]); 811 812#if CHAN_TYPE == GL_FLOAT 813 _mesa_debug(ctx, "color %f %f %f %f\n", 814 v->color[0], v->color[1], v->color[2], v->color[3]); 815 _mesa_debug(ctx, "spec %f %f %f %f\n", 816 v->specular[0], v->specular[1], 817 v->specular[2], v->specular[3]); 818#else 819 _mesa_debug(ctx, "color %d %d %d %d\n", 820 v->color[0], v->color[1], v->color[2], v->color[3]); 821 _mesa_debug(ctx, "spec %d %d %d %d\n", 822 v->specular[0], v->specular[1], 823 v->specular[2], v->specular[3]); 824#endif 825 _mesa_debug(ctx, "fog %f\n", v->fog); 826 _mesa_debug(ctx, "index %d\n", v->index); 827 _mesa_debug(ctx, "pointsize %f\n", v->pointSize); 828 _mesa_debug(ctx, "\n"); 829 } 830} 831