s_context.c revision 0397b2bb41b0f337af2949a15bcd7d0e7e8a7dc1
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.1 4 * 5 * Copyright (C) 1999-2008 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 "main/imports.h" 30#include "bufferobj.h" 31#include "main/context.h" 32#include "main/colormac.h" 33#include "main/mtypes.h" 34#include "teximage.h" 35#include "swrast.h" 36#include "shader/prog_parameter.h" 37#include "shader/prog_statevars.h" 38#include "s_blend.h" 39#include "s_context.h" 40#include "s_lines.h" 41#include "s_points.h" 42#include "s_span.h" 43#include "s_triangle.h" 44#include "s_texfilter.h" 45 46 47/** 48 * Recompute the value of swrast->_RasterMask, etc. according to 49 * the current context. The _RasterMask field can be easily tested by 50 * drivers to determine certain basic GL state (does the primitive need 51 * stenciling, logic-op, fog, etc?). 52 */ 53static void 54_swrast_update_rasterflags( GLcontext *ctx ) 55{ 56 SWcontext *swrast = SWRAST_CONTEXT(ctx); 57 GLbitfield rasterMask = 0; 58 59 if (ctx->Color.AlphaEnabled) rasterMask |= ALPHATEST_BIT; 60 if (ctx->Color.BlendEnabled) rasterMask |= BLEND_BIT; 61 if (ctx->Depth.Test) rasterMask |= DEPTH_BIT; 62 if (swrast->_FogEnabled) rasterMask |= FOG_BIT; 63 if (ctx->Scissor.Enabled) rasterMask |= CLIP_BIT; 64 if (ctx->Stencil.Enabled) rasterMask |= STENCIL_BIT; 65 if (ctx->Visual.rgbMode) { 66 const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); 67 if (colorMask != 0xffffffff) rasterMask |= MASKING_BIT; 68 if (ctx->Color._LogicOpEnabled) rasterMask |= LOGIC_OP_BIT; 69 if (ctx->Texture._EnabledUnits) rasterMask |= TEXTURE_BIT; 70 } 71 else { 72 if (ctx->Color.IndexMask != 0xffffffff) rasterMask |= MASKING_BIT; 73 if (ctx->Color.IndexLogicOpEnabled) rasterMask |= LOGIC_OP_BIT; 74 } 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->Query.CurrentOcclusionObject) 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->DrawBuffer->_NumColorDrawBuffers != 1) { 92 /* more than one color buffer designated for writing (or zero buffers) */ 93 rasterMask |= MULTI_DRAW_BIT; 94 } 95 else if (ctx->Visual.rgbMode && *((GLuint *) ctx->Color.ColorMask) == 0) { 96 rasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */ 97 } 98 else if (!ctx->Visual.rgbMode && ctx->Color.IndexMask==0) { 99 rasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */ 100 } 101 102 if (ctx->FragmentProgram._Current) { 103 rasterMask |= FRAGPROG_BIT; 104 } 105 106 if (ctx->ATIFragmentShader._Enabled) { 107 rasterMask |= ATIFRAGSHADER_BIT; 108 } 109 110#if CHAN_TYPE == GL_FLOAT 111 if (ctx->Color.ClampFragmentColor == GL_TRUE) { 112 rasterMask |= CLAMPING_BIT; 113 } 114#endif 115 116 SWRAST_CONTEXT(ctx)->_RasterMask = rasterMask; 117} 118 119 120/** 121 * Examine polygon cull state to compute the _BackfaceCullSign field. 122 * _BackfaceCullSign will be 0 if no culling, -1 if culling back-faces, 123 * and 1 if culling front-faces. The Polygon FrontFace state also 124 * factors in. 125 */ 126static void 127_swrast_update_polygon( GLcontext *ctx ) 128{ 129 GLfloat backface_sign; 130 131 if (ctx->Polygon.CullFlag) { 132 switch (ctx->Polygon.CullFaceMode) { 133 case GL_BACK: 134 backface_sign = -1.0; 135 break; 136 case GL_FRONT: 137 backface_sign = 1.0; 138 break; 139 case GL_FRONT_AND_BACK: 140 /* fallthrough */ 141 default: 142 backface_sign = 0.0; 143 } 144 } 145 else { 146 backface_sign = 0.0; 147 } 148 149 SWRAST_CONTEXT(ctx)->_BackfaceCullSign = backface_sign; 150 151 /* This is for front/back-face determination, but not for culling */ 152 SWRAST_CONTEXT(ctx)->_BackfaceSign 153 = (ctx->Polygon.FrontFace == GL_CW) ? -1.0 : 1.0; 154} 155 156 157 158/** 159 * Update the _PreferPixelFog field to indicate if we need to compute 160 * fog blend factors (from the fog coords) per-fragment. 161 */ 162static void 163_swrast_update_fog_hint( GLcontext *ctx ) 164{ 165 SWcontext *swrast = SWRAST_CONTEXT(ctx); 166 swrast->_PreferPixelFog = (!swrast->AllowVertexFog || 167 ctx->FragmentProgram._Current || 168 (ctx->Hint.Fog == GL_NICEST && 169 swrast->AllowPixelFog)); 170} 171 172 173 174/** 175 * Update the swrast->_AnyTextureCombine flag. 176 */ 177static void 178_swrast_update_texture_env( GLcontext *ctx ) 179{ 180 SWcontext *swrast = SWRAST_CONTEXT(ctx); 181 GLuint i; 182 swrast->_AnyTextureCombine = GL_FALSE; 183 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 184 if (ctx->Texture.Unit[i].EnvMode == GL_COMBINE_EXT || 185 ctx->Texture.Unit[i].EnvMode == GL_COMBINE4_NV) { 186 swrast->_AnyTextureCombine = GL_TRUE; 187 return; 188 } 189 } 190} 191 192 193/** 194 * Determine if we can defer texturing/shading until after Z/stencil 195 * testing. This potentially allows us to skip texturing/shading for 196 * lots of fragments. 197 */ 198static void 199_swrast_update_deferred_texture(GLcontext *ctx) 200{ 201 SWcontext *swrast = SWRAST_CONTEXT(ctx); 202 if (ctx->Color.AlphaEnabled) { 203 /* alpha test depends on post-texture/shader colors */ 204 swrast->_DeferredTexture = GL_FALSE; 205 } 206 else { 207 const struct gl_fragment_program *fprog 208 = ctx->FragmentProgram._Current; 209 if (fprog && (fprog->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR))) { 210 /* Z comes from fragment program/shader */ 211 swrast->_DeferredTexture = GL_FALSE; 212 } 213 else if (ctx->Query.CurrentOcclusionObject) { 214 /* occlusion query depends on shader discard/kill results */ 215 swrast->_DeferredTexture = GL_FALSE; 216 } 217 else { 218 swrast->_DeferredTexture = GL_TRUE; 219 } 220 } 221} 222 223 224/** 225 * Update swrast->_FogColor and swrast->_FogEnable values. 226 */ 227static void 228_swrast_update_fog_state( GLcontext *ctx ) 229{ 230 SWcontext *swrast = SWRAST_CONTEXT(ctx); 231 const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; 232 233 /* determine if fog is needed, and if so, which fog mode */ 234 swrast->_FogEnabled = GL_FALSE; 235 if (fp && fp->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { 236 if (fp->FogOption != GL_NONE) { 237 swrast->_FogEnabled = GL_TRUE; 238 swrast->_FogMode = fp->FogOption; 239 } 240 } 241 else if (ctx->Fog.Enabled) { 242 swrast->_FogEnabled = GL_TRUE; 243 swrast->_FogMode = ctx->Fog.Mode; 244 } 245} 246 247 248/** 249 * Update state for running fragment programs. Basically, load the 250 * program parameters with current state values. 251 */ 252static void 253_swrast_update_fragment_program(GLcontext *ctx, GLbitfield newState) 254{ 255 const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; 256 if (fp) { 257#if 0 258 /* XXX Need a way to trigger the initial loading of parameters 259 * even when there's no recent state changes. 260 */ 261 if (fp->Base.Parameters->StateFlags & newState) 262#endif 263 _mesa_load_state_parameters(ctx, fp->Base.Parameters); 264 } 265} 266 267 268 269#define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK | \ 270 _NEW_TEXTURE | \ 271 _NEW_HINT | \ 272 _NEW_POLYGON ) 273 274/* State referenced by _swrast_choose_triangle, _swrast_choose_line. 275 */ 276#define _SWRAST_NEW_TRIANGLE (_SWRAST_NEW_DERIVED | \ 277 _NEW_RENDERMODE| \ 278 _NEW_POLYGON| \ 279 _NEW_DEPTH| \ 280 _NEW_STENCIL| \ 281 _NEW_COLOR| \ 282 _NEW_TEXTURE| \ 283 _SWRAST_NEW_RASTERMASK| \ 284 _NEW_LIGHT| \ 285 _NEW_FOG | \ 286 _DD_NEW_SEPARATE_SPECULAR) 287 288#define _SWRAST_NEW_LINE (_SWRAST_NEW_DERIVED | \ 289 _NEW_RENDERMODE| \ 290 _NEW_LINE| \ 291 _NEW_TEXTURE| \ 292 _NEW_LIGHT| \ 293 _NEW_FOG| \ 294 _NEW_DEPTH | \ 295 _DD_NEW_SEPARATE_SPECULAR) 296 297#define _SWRAST_NEW_POINT (_SWRAST_NEW_DERIVED | \ 298 _NEW_RENDERMODE | \ 299 _NEW_POINT | \ 300 _NEW_TEXTURE | \ 301 _NEW_LIGHT | \ 302 _NEW_FOG | \ 303 _DD_NEW_SEPARATE_SPECULAR) 304 305#define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE 306 307#define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE 308 309#define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR 310 311 312 313/** 314 * Stub for swrast->Triangle to select a true triangle function 315 * after a state change. 316 */ 317static void 318_swrast_validate_triangle( GLcontext *ctx, 319 const SWvertex *v0, 320 const SWvertex *v1, 321 const SWvertex *v2 ) 322{ 323 SWcontext *swrast = SWRAST_CONTEXT(ctx); 324 325 _swrast_validate_derived( ctx ); 326 swrast->choose_triangle( ctx ); 327 ASSERT(swrast->Triangle); 328 329 if (ctx->Texture._EnabledUnits == 0 330 && NEED_SECONDARY_COLOR(ctx) 331 && !ctx->FragmentProgram._Current) { 332 /* separate specular color, but no texture */ 333 swrast->SpecTriangle = swrast->Triangle; 334 swrast->Triangle = _swrast_add_spec_terms_triangle; 335 } 336 337 swrast->Triangle( ctx, v0, v1, v2 ); 338} 339 340/** 341 * Called via swrast->Line. Examine current GL state and choose a software 342 * line routine. Then call it. 343 */ 344static void 345_swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) 346{ 347 SWcontext *swrast = SWRAST_CONTEXT(ctx); 348 349 _swrast_validate_derived( ctx ); 350 swrast->choose_line( ctx ); 351 ASSERT(swrast->Line); 352 353 if (ctx->Texture._EnabledUnits == 0 354 && NEED_SECONDARY_COLOR(ctx) 355 && !ctx->FragmentProgram._Current) { 356 swrast->SpecLine = swrast->Line; 357 swrast->Line = _swrast_add_spec_terms_line; 358 } 359 360 swrast->Line( ctx, v0, v1 ); 361} 362 363/** 364 * Called via swrast->Point. Examine current GL state and choose a software 365 * point routine. Then call it. 366 */ 367static void 368_swrast_validate_point( GLcontext *ctx, const SWvertex *v0 ) 369{ 370 SWcontext *swrast = SWRAST_CONTEXT(ctx); 371 372 _swrast_validate_derived( ctx ); 373 swrast->choose_point( ctx ); 374 375 if (ctx->Texture._EnabledUnits == 0 376 && NEED_SECONDARY_COLOR(ctx) 377 && !ctx->FragmentProgram._Current) { 378 swrast->SpecPoint = swrast->Point; 379 swrast->Point = _swrast_add_spec_terms_point; 380 } 381 382 swrast->Point( ctx, v0 ); 383} 384 385 386/** 387 * Called via swrast->BlendFunc. Examine GL state to choose a blending 388 * function, then call it. 389 */ 390static void _ASMAPI 391_swrast_validate_blend_func(GLcontext *ctx, GLuint n, const GLubyte mask[], 392 GLvoid *src, const GLvoid *dst, 393 GLenum chanType ) 394{ 395 SWcontext *swrast = SWRAST_CONTEXT(ctx); 396 397 _swrast_validate_derived( ctx ); /* why is this needed? */ 398 _swrast_choose_blend_func( ctx, chanType ); 399 400 swrast->BlendFunc( ctx, n, mask, src, dst, chanType ); 401} 402 403 404/** 405 * Make sure we have texture image data for all the textures we may need 406 * for subsequent rendering. 407 */ 408static void 409_swrast_validate_texture_images(GLcontext *ctx) 410{ 411 SWcontext *swrast = SWRAST_CONTEXT(ctx); 412 GLuint u; 413 414 if (!swrast->ValidateTextureImage || !ctx->Texture._EnabledUnits) { 415 /* no textures enabled, or no way to validate images! */ 416 return; 417 } 418 419 for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) { 420 if (ctx->Texture.Unit[u]._ReallyEnabled) { 421 struct gl_texture_object *texObj = ctx->Texture.Unit[u]._Current; 422 ASSERT(texObj); 423 if (texObj) { 424 GLuint numFaces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 425 GLuint face; 426 for (face = 0; face < numFaces; face++) { 427 GLint lvl; 428 for (lvl = texObj->BaseLevel; lvl <= texObj->_MaxLevel; lvl++) { 429 struct gl_texture_image *texImg = texObj->Image[face][lvl]; 430 if (texImg && !texImg->Data) { 431 swrast->ValidateTextureImage(ctx, texObj, face, lvl); 432 ASSERT(texObj->Image[face][lvl]->Data); 433 } 434 } 435 } 436 } 437 } 438 } 439} 440 441 442/** 443 * Free the texture image data attached to all currently enabled 444 * textures. Meant to be called by device drivers when transitioning 445 * from software to hardware rendering. 446 */ 447void 448_swrast_eject_texture_images(GLcontext *ctx) 449{ 450 GLuint u; 451 452 if (!ctx->Texture._EnabledUnits) { 453 /* no textures enabled */ 454 return; 455 } 456 457 for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) { 458 if (ctx->Texture.Unit[u]._ReallyEnabled) { 459 struct gl_texture_object *texObj = ctx->Texture.Unit[u]._Current; 460 ASSERT(texObj); 461 if (texObj) { 462 GLuint numFaces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 463 GLuint face; 464 for (face = 0; face < numFaces; face++) { 465 GLint lvl; 466 for (lvl = texObj->BaseLevel; lvl <= texObj->_MaxLevel; lvl++) { 467 struct gl_texture_image *texImg = texObj->Image[face][lvl]; 468 if (texImg && texImg->Data) { 469 _mesa_free_texmemory(texImg->Data); 470 texImg->Data = NULL; 471 } 472 } 473 } 474 } 475 } 476 } 477} 478 479 480 481static void 482_swrast_sleep( GLcontext *ctx, GLbitfield new_state ) 483{ 484 (void) ctx; (void) new_state; 485} 486 487 488static void 489_swrast_invalidate_state( GLcontext *ctx, GLbitfield new_state ) 490{ 491 SWcontext *swrast = SWRAST_CONTEXT(ctx); 492 GLuint i; 493 494 swrast->NewState |= new_state; 495 496 /* After 10 statechanges without any swrast functions being called, 497 * put the module to sleep. 498 */ 499 if (++swrast->StateChanges > 10) { 500 swrast->InvalidateState = _swrast_sleep; 501 swrast->NewState = ~0; 502 new_state = ~0; 503 } 504 505 { 506 const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; 507 if (fp && (fp->Base.Parameters->StateFlags & new_state)) { 508 _mesa_load_state_parameters(ctx, fp->Base.Parameters); 509 } 510 } 511 512 if (new_state & swrast->InvalidateTriangleMask) 513 swrast->Triangle = _swrast_validate_triangle; 514 515 if (new_state & swrast->InvalidateLineMask) 516 swrast->Line = _swrast_validate_line; 517 518 if (new_state & swrast->InvalidatePointMask) 519 swrast->Point = _swrast_validate_point; 520 521 if (new_state & _SWRAST_NEW_BLEND_FUNC) 522 swrast->BlendFunc = _swrast_validate_blend_func; 523 524 if (new_state & _SWRAST_NEW_TEXTURE_SAMPLE_FUNC) 525 for (i = 0 ; i < ctx->Const.MaxTextureImageUnits ; i++) 526 swrast->TextureSample[i] = NULL; 527} 528 529 530void 531_swrast_update_texture_samplers(GLcontext *ctx) 532{ 533 SWcontext *swrast = SWRAST_CONTEXT(ctx); 534 GLuint u; 535 536 if (!swrast) 537 return; /* pipe hack */ 538 539 for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) { 540 const struct gl_texture_object *tObj = ctx->Texture.Unit[u]._Current; 541 /* Note: If tObj is NULL, the sample function will be a simple 542 * function that just returns opaque black (0,0,0,1). 543 */ 544 swrast->TextureSample[u] = _swrast_choose_texture_sample_func(ctx, tObj); 545 } 546} 547 548 549/** 550 * Update swrast->_ActiveAttribs, swrast->_NumActiveAttribs, 551 * swrast->_ActiveAtttribMask. 552 */ 553static void 554_swrast_update_active_attribs(GLcontext *ctx) 555{ 556 SWcontext *swrast = SWRAST_CONTEXT(ctx); 557 GLuint attribsMask; 558 559 /* 560 * Compute _ActiveAttribsMask = which fragment attributes are needed. 561 */ 562 if (ctx->FragmentProgram._Current) { 563 /* fragment program/shader */ 564 attribsMask = ctx->FragmentProgram._Current->Base.InputsRead; 565 attribsMask &= ~FRAG_BIT_WPOS; /* WPOS is always handled specially */ 566 } 567 else if (ctx->ATIFragmentShader._Enabled) { 568 attribsMask = ~0; /* XXX fix me */ 569 } 570 else { 571 /* fixed function */ 572 attribsMask = 0x0; 573 574#if CHAN_TYPE == GL_FLOAT 575 attribsMask |= FRAG_BIT_COL0; 576#endif 577 578 if (ctx->Fog.ColorSumEnabled || 579 (ctx->Light.Enabled && 580 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { 581 attribsMask |= FRAG_BIT_COL1; 582 } 583 584 if (swrast->_FogEnabled) 585 attribsMask |= FRAG_BIT_FOGC; 586 587 attribsMask |= (ctx->Texture._EnabledUnits << FRAG_ATTRIB_TEX0); 588 } 589 590 swrast->_ActiveAttribMask = attribsMask; 591 592 /* Update _ActiveAttribs[] list */ 593 { 594 GLuint i, num = 0; 595 for (i = 0; i < FRAG_ATTRIB_MAX; i++) { 596 if (attribsMask & (1 << i)) { 597 swrast->_ActiveAttribs[num++] = i; 598 /* how should this attribute be interpolated? */ 599 if (i == FRAG_ATTRIB_COL0 || i == FRAG_ATTRIB_COL1) 600 swrast->_InterpMode[i] = ctx->Light.ShadeModel; 601 else 602 swrast->_InterpMode[i] = GL_SMOOTH; 603 } 604 } 605 swrast->_NumActiveAttribs = num; 606 } 607} 608 609 610void 611_swrast_validate_derived( GLcontext *ctx ) 612{ 613 SWcontext *swrast = SWRAST_CONTEXT(ctx); 614 615 if (swrast->NewState) { 616 if (swrast->NewState & _NEW_POLYGON) 617 _swrast_update_polygon( ctx ); 618 619 if (swrast->NewState & (_NEW_HINT | _NEW_PROGRAM)) 620 _swrast_update_fog_hint( ctx ); 621 622 if (swrast->NewState & _SWRAST_NEW_TEXTURE_ENV_MODE) 623 _swrast_update_texture_env( ctx ); 624 625 if (swrast->NewState & (_NEW_FOG | _NEW_PROGRAM)) 626 _swrast_update_fog_state( ctx ); 627 628 if (swrast->NewState & (_NEW_MODELVIEW | 629 _NEW_PROJECTION | 630 _NEW_TEXTURE_MATRIX | 631 _NEW_FOG | 632 _NEW_LIGHT | 633 _NEW_LINE | 634 _NEW_TEXTURE | 635 _NEW_TRANSFORM | 636 _NEW_POINT | 637 _NEW_VIEWPORT | 638 _NEW_PROGRAM)) 639 _swrast_update_fragment_program( ctx, swrast->NewState ); 640 641 if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM)) { 642 _swrast_update_texture_samplers( ctx ); 643 _swrast_validate_texture_images(ctx); 644 } 645 646 if (swrast->NewState & (_NEW_COLOR | _NEW_PROGRAM)) 647 _swrast_update_deferred_texture(ctx); 648 649 if (swrast->NewState & _SWRAST_NEW_RASTERMASK) 650 _swrast_update_rasterflags( ctx ); 651 652 if (swrast->NewState & (_NEW_DEPTH | 653 _NEW_FOG | 654 _NEW_LIGHT | 655 _NEW_PROGRAM | 656 _NEW_TEXTURE)) 657 _swrast_update_active_attribs(ctx); 658 659 swrast->NewState = 0; 660 swrast->StateChanges = 0; 661 swrast->InvalidateState = _swrast_invalidate_state; 662 } 663} 664 665#define SWRAST_DEBUG 0 666 667/* Public entrypoints: See also s_accum.c, s_bitmap.c, etc. 668 */ 669void 670_swrast_Quad( GLcontext *ctx, 671 const SWvertex *v0, const SWvertex *v1, 672 const SWvertex *v2, const SWvertex *v3 ) 673{ 674 if (SWRAST_DEBUG) { 675 _mesa_debug(ctx, "_swrast_Quad\n"); 676 _swrast_print_vertex( ctx, v0 ); 677 _swrast_print_vertex( ctx, v1 ); 678 _swrast_print_vertex( ctx, v2 ); 679 _swrast_print_vertex( ctx, v3 ); 680 } 681 SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v3 ); 682 SWRAST_CONTEXT(ctx)->Triangle( ctx, v1, v2, v3 ); 683} 684 685void 686_swrast_Triangle( GLcontext *ctx, const SWvertex *v0, 687 const SWvertex *v1, const SWvertex *v2 ) 688{ 689 if (SWRAST_DEBUG) { 690 _mesa_debug(ctx, "_swrast_Triangle\n"); 691 _swrast_print_vertex( ctx, v0 ); 692 _swrast_print_vertex( ctx, v1 ); 693 _swrast_print_vertex( ctx, v2 ); 694 } 695 SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 ); 696} 697 698void 699_swrast_Line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) 700{ 701 if (SWRAST_DEBUG) { 702 _mesa_debug(ctx, "_swrast_Line\n"); 703 _swrast_print_vertex( ctx, v0 ); 704 _swrast_print_vertex( ctx, v1 ); 705 } 706 SWRAST_CONTEXT(ctx)->Line( ctx, v0, v1 ); 707} 708 709void 710_swrast_Point( GLcontext *ctx, const SWvertex *v0 ) 711{ 712 if (SWRAST_DEBUG) { 713 _mesa_debug(ctx, "_swrast_Point\n"); 714 _swrast_print_vertex( ctx, v0 ); 715 } 716 SWRAST_CONTEXT(ctx)->Point( ctx, v0 ); 717} 718 719void 720_swrast_InvalidateState( GLcontext *ctx, GLbitfield new_state ) 721{ 722 if (SWRAST_DEBUG) { 723 _mesa_debug(ctx, "_swrast_InvalidateState\n"); 724 } 725 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, new_state ); 726} 727 728void 729_swrast_ResetLineStipple( GLcontext *ctx ) 730{ 731 if (SWRAST_DEBUG) { 732 _mesa_debug(ctx, "_swrast_ResetLineStipple\n"); 733 } 734 SWRAST_CONTEXT(ctx)->StippleCounter = 0; 735} 736 737void 738_swrast_SetFacing(GLcontext *ctx, GLuint facing) 739{ 740 SWRAST_CONTEXT(ctx)->PointLineFacing = facing; 741} 742 743void 744_swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value ) 745{ 746 if (SWRAST_DEBUG) { 747 _mesa_debug(ctx, "_swrast_allow_vertex_fog %d\n", value); 748 } 749 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); 750 SWRAST_CONTEXT(ctx)->AllowVertexFog = value; 751} 752 753void 754_swrast_allow_pixel_fog( GLcontext *ctx, GLboolean value ) 755{ 756 if (SWRAST_DEBUG) { 757 _mesa_debug(ctx, "_swrast_allow_pixel_fog %d\n", value); 758 } 759 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); 760 SWRAST_CONTEXT(ctx)->AllowPixelFog = value; 761} 762 763 764GLboolean 765_swrast_CreateContext( GLcontext *ctx ) 766{ 767 GLuint i; 768 SWcontext *swrast = (SWcontext *)CALLOC(sizeof(SWcontext)); 769 770 if (SWRAST_DEBUG) { 771 _mesa_debug(ctx, "_swrast_CreateContext\n"); 772 } 773 774 if (!swrast) 775 return GL_FALSE; 776 777 swrast->NewState = ~0; 778 779 swrast->choose_point = _swrast_choose_point; 780 swrast->choose_line = _swrast_choose_line; 781 swrast->choose_triangle = _swrast_choose_triangle; 782 783 swrast->InvalidatePointMask = _SWRAST_NEW_POINT; 784 swrast->InvalidateLineMask = _SWRAST_NEW_LINE; 785 swrast->InvalidateTriangleMask = _SWRAST_NEW_TRIANGLE; 786 787 swrast->Point = _swrast_validate_point; 788 swrast->Line = _swrast_validate_line; 789 swrast->Triangle = _swrast_validate_triangle; 790 swrast->InvalidateState = _swrast_sleep; 791 swrast->BlendFunc = _swrast_validate_blend_func; 792 793 swrast->AllowVertexFog = GL_TRUE; 794 swrast->AllowPixelFog = GL_TRUE; 795 796 /* Optimized Accum buffer */ 797 swrast->_IntegerAccumMode = GL_FALSE; 798 swrast->_IntegerAccumScaler = 0.0; 799 800 for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) 801 swrast->TextureSample[i] = NULL; 802 803 swrast->SpanArrays = MALLOC_STRUCT(sw_span_arrays); 804 if (!swrast->SpanArrays) { 805 FREE(swrast); 806 return GL_FALSE; 807 } 808 swrast->SpanArrays->ChanType = CHAN_TYPE; 809#if CHAN_TYPE == GL_UNSIGNED_BYTE 810 swrast->SpanArrays->rgba = swrast->SpanArrays->rgba8; 811#elif CHAN_TYPE == GL_UNSIGNED_SHORT 812 swrast->SpanArrays->rgba = swrast->SpanArrays->rgba16; 813#else 814 swrast->SpanArrays->rgba = swrast->SpanArrays->attribs[FRAG_ATTRIB_COL0]; 815#endif 816 817 /* init point span buffer */ 818 swrast->PointSpan.primitive = GL_POINT; 819 swrast->PointSpan.end = 0; 820 swrast->PointSpan.facing = 0; 821 swrast->PointSpan.array = swrast->SpanArrays; 822 823 swrast->TexelBuffer = (GLchan *) MALLOC(ctx->Const.MaxTextureImageUnits * 824 MAX_WIDTH * 4 * sizeof(GLchan)); 825 if (!swrast->TexelBuffer) { 826 FREE(swrast->SpanArrays); 827 FREE(swrast); 828 return GL_FALSE; 829 } 830 831 ctx->swrast_context = swrast; 832 833 return GL_TRUE; 834} 835 836void 837_swrast_DestroyContext( GLcontext *ctx ) 838{ 839 SWcontext *swrast = SWRAST_CONTEXT(ctx); 840 841 if (SWRAST_DEBUG) { 842 _mesa_debug(ctx, "_swrast_DestroyContext\n"); 843 } 844 845 FREE( swrast->SpanArrays ); 846 if (swrast->ZoomedArrays) 847 FREE( swrast->ZoomedArrays ); 848 FREE( swrast->TexelBuffer ); 849 FREE( swrast ); 850 851 ctx->swrast_context = 0; 852} 853 854 855struct swrast_device_driver * 856_swrast_GetDeviceDriverReference( GLcontext *ctx ) 857{ 858 SWcontext *swrast = SWRAST_CONTEXT(ctx); 859 return &swrast->Driver; 860} 861 862void 863_swrast_flush( GLcontext *ctx ) 864{ 865 SWcontext *swrast = SWRAST_CONTEXT(ctx); 866 /* flush any pending fragments from rendering points */ 867 if (swrast->PointSpan.end > 0) { 868 if (ctx->Visual.rgbMode) { 869 _swrast_write_rgba_span(ctx, &(swrast->PointSpan)); 870 } 871 else { 872 _swrast_write_index_span(ctx, &(swrast->PointSpan)); 873 } 874 swrast->PointSpan.end = 0; 875 } 876} 877 878void 879_swrast_render_primitive( GLcontext *ctx, GLenum prim ) 880{ 881 SWcontext *swrast = SWRAST_CONTEXT(ctx); 882 if (swrast->Primitive == GL_POINTS && prim != GL_POINTS) { 883 _swrast_flush(ctx); 884 } 885 swrast->Primitive = prim; 886} 887 888 889void 890_swrast_render_start( GLcontext *ctx ) 891{ 892 SWcontext *swrast = SWRAST_CONTEXT(ctx); 893 if (swrast->Driver.SpanRenderStart) 894 swrast->Driver.SpanRenderStart( ctx ); 895 swrast->PointSpan.end = 0; 896} 897 898void 899_swrast_render_finish( GLcontext *ctx ) 900{ 901 SWcontext *swrast = SWRAST_CONTEXT(ctx); 902 if (swrast->Driver.SpanRenderFinish) 903 swrast->Driver.SpanRenderFinish( ctx ); 904 905 _swrast_flush(ctx); 906} 907 908 909#define SWRAST_DEBUG_VERTICES 0 910 911void 912_swrast_print_vertex( GLcontext *ctx, const SWvertex *v ) 913{ 914 GLuint i; 915 916 if (SWRAST_DEBUG_VERTICES) { 917 _mesa_debug(ctx, "win %f %f %f %f\n", 918 v->attrib[FRAG_ATTRIB_WPOS][0], 919 v->attrib[FRAG_ATTRIB_WPOS][1], 920 v->attrib[FRAG_ATTRIB_WPOS][2], 921 v->attrib[FRAG_ATTRIB_WPOS][3]); 922 923 for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) 924 if (ctx->Texture.Unit[i]._ReallyEnabled) 925 _mesa_debug(ctx, "texcoord[%d] %f %f %f %f\n", i, 926 v->attrib[FRAG_ATTRIB_TEX0 + i][0], 927 v->attrib[FRAG_ATTRIB_TEX0 + i][1], 928 v->attrib[FRAG_ATTRIB_TEX0 + i][2], 929 v->attrib[FRAG_ATTRIB_TEX0 + i][3]); 930 931#if CHAN_TYPE == GL_FLOAT 932 _mesa_debug(ctx, "color %f %f %f %f\n", 933 v->color[0], v->color[1], v->color[2], v->color[3]); 934#else 935 _mesa_debug(ctx, "color %d %d %d %d\n", 936 v->color[0], v->color[1], v->color[2], v->color[3]); 937#endif 938 _mesa_debug(ctx, "spec %g %g %g %g\n", 939 v->attrib[FRAG_ATTRIB_COL1][0], 940 v->attrib[FRAG_ATTRIB_COL1][1], 941 v->attrib[FRAG_ATTRIB_COL1][2], 942 v->attrib[FRAG_ATTRIB_COL1][3]); 943 _mesa_debug(ctx, "fog %f\n", v->attrib[FRAG_ATTRIB_FOGC][0]); 944 _mesa_debug(ctx, "index %d\n", v->attrib[FRAG_ATTRIB_CI][0]); 945 _mesa_debug(ctx, "pointsize %f\n", v->pointSize); 946 _mesa_debug(ctx, "\n"); 947 } 948} 949