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