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