1 /* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Keith Whitwell <keithw (at) vmware.com> Brian Paul 26 */ 27 28 #include "main/imports.h" 29 #include "main/bufferobj.h" 30 #include "main/mtypes.h" 31 #include "main/samplerobj.h" 32 #include "main/teximage.h" 33 #include "program/prog_parameter.h" 34 #include "program/prog_statevars.h" 35 #include "swrast.h" 36 #include "s_blend.h" 37 #include "s_context.h" 38 #include "s_lines.h" 39 #include "s_points.h" 40 #include "s_span.h" 41 #include "s_texfetch.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 */ 52 static void 53 _swrast_update_rasterflags( struct gl_context *ctx ) 54 { 55 SWcontext *swrast = SWRAST_CONTEXT(ctx); 56 GLbitfield rasterMask = 0; 57 GLuint i; 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.EnableFlags) rasterMask |= CLIP_BIT; 64 if (ctx->Stencil._Enabled) rasterMask |= STENCIL_BIT; 65 for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { 66 if (!ctx->Color.ColorMask[i][0] || 67 !ctx->Color.ColorMask[i][1] || 68 !ctx->Color.ColorMask[i][2] || 69 !ctx->Color.ColorMask[i][3]) { 70 rasterMask |= MASKING_BIT; 71 break; 72 } 73 } 74 if (ctx->Color.ColorLogicOpEnabled) rasterMask |= LOGIC_OP_BIT; 75 if (ctx->Texture._MaxEnabledTexImageUnit >= 0) rasterMask |= TEXTURE_BIT; 76 if ( ctx->ViewportArray[0].X < 0 77 || ctx->ViewportArray[0].X + ctx->ViewportArray[0].Width > (GLfloat) ctx->DrawBuffer->Width 78 || ctx->ViewportArray[0].Y < 0 79 || ctx->ViewportArray[0].Y + ctx->ViewportArray[0].Height > (GLfloat) 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 96 for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { 97 if (ctx->Color.ColorMask[i][0] + 98 ctx->Color.ColorMask[i][1] + 99 ctx->Color.ColorMask[i][2] + 100 ctx->Color.ColorMask[i][3] == 0) { 101 rasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */ 102 break; 103 } 104 } 105 106 107 if (_swrast_use_fragment_program(ctx)) { 108 rasterMask |= FRAGPROG_BIT; 109 } 110 111 if (ctx->ATIFragmentShader._Enabled) { 112 rasterMask |= ATIFRAGSHADER_BIT; 113 } 114 115 #if CHAN_TYPE == GL_FLOAT 116 if (ctx->Color.ClampFragmentColor == GL_TRUE) { 117 rasterMask |= CLAMPING_BIT; 118 } 119 #endif 120 121 SWRAST_CONTEXT(ctx)->_RasterMask = rasterMask; 122 } 123 124 125 /** 126 * Examine polygon cull state to compute the _BackfaceCullSign field. 127 * _BackfaceCullSign will be 0 if no culling, -1 if culling back-faces, 128 * and 1 if culling front-faces. The Polygon FrontFace state also 129 * factors in. 130 */ 131 static void 132 _swrast_update_polygon( struct gl_context *ctx ) 133 { 134 GLfloat backface_sign; 135 136 if (ctx->Polygon.CullFlag) { 137 switch (ctx->Polygon.CullFaceMode) { 138 case GL_BACK: 139 backface_sign = -1.0F; 140 break; 141 case GL_FRONT: 142 backface_sign = 1.0F; 143 break; 144 case GL_FRONT_AND_BACK: 145 /* fallthrough */ 146 default: 147 backface_sign = 0.0F; 148 } 149 } 150 else { 151 backface_sign = 0.0F; 152 } 153 154 SWRAST_CONTEXT(ctx)->_BackfaceCullSign = backface_sign; 155 156 /* This is for front/back-face determination, but not for culling */ 157 SWRAST_CONTEXT(ctx)->_BackfaceSign 158 = (ctx->Polygon.FrontFace == GL_CW) ? -1.0F : 1.0F; 159 } 160 161 162 163 /** 164 * Update the _PreferPixelFog field to indicate if we need to compute 165 * fog blend factors (from the fog coords) per-fragment. 166 */ 167 static void 168 _swrast_update_fog_hint( struct gl_context *ctx ) 169 { 170 SWcontext *swrast = SWRAST_CONTEXT(ctx); 171 swrast->_PreferPixelFog = (!swrast->AllowVertexFog || 172 _swrast_use_fragment_program(ctx) || 173 (ctx->Hint.Fog == GL_NICEST && 174 swrast->AllowPixelFog)); 175 } 176 177 178 179 /** 180 * Update the swrast->_TextureCombinePrimary flag. 181 */ 182 static void 183 _swrast_update_texture_env( struct gl_context *ctx ) 184 { 185 SWcontext *swrast = SWRAST_CONTEXT(ctx); 186 GLuint i; 187 188 swrast->_TextureCombinePrimary = GL_FALSE; 189 190 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 191 const struct gl_tex_env_combine_state *combine = 192 ctx->Texture.Unit[i]._CurrentCombine; 193 GLuint term; 194 for (term = 0; term < combine->_NumArgsRGB; term++) { 195 if (combine->SourceRGB[term] == GL_PRIMARY_COLOR) { 196 swrast->_TextureCombinePrimary = GL_TRUE; 197 return; 198 } 199 if (combine->SourceA[term] == GL_PRIMARY_COLOR) { 200 swrast->_TextureCombinePrimary = GL_TRUE; 201 return; 202 } 203 } 204 } 205 } 206 207 208 /** 209 * Determine if we can defer texturing/shading until after Z/stencil 210 * testing. This potentially allows us to skip texturing/shading for 211 * lots of fragments. 212 */ 213 static void 214 _swrast_update_deferred_texture(struct gl_context *ctx) 215 { 216 SWcontext *swrast = SWRAST_CONTEXT(ctx); 217 if (ctx->Color.AlphaEnabled) { 218 /* alpha test depends on post-texture/shader colors */ 219 swrast->_DeferredTexture = GL_FALSE; 220 } 221 else { 222 GLboolean use_fprog = _swrast_use_fragment_program(ctx); 223 const struct gl_program *fprog = ctx->FragmentProgram._Current; 224 if (use_fprog && 225 (fprog->info.outputs_written & (1 << FRAG_RESULT_DEPTH))) { 226 /* Z comes from fragment program/shader */ 227 swrast->_DeferredTexture = GL_FALSE; 228 } 229 else if (use_fprog && fprog->info.fs.uses_discard) { 230 swrast->_DeferredTexture = GL_FALSE; 231 } 232 else if (ctx->Query.CurrentOcclusionObject) { 233 /* occlusion query depends on shader discard/kill results */ 234 swrast->_DeferredTexture = GL_FALSE; 235 } 236 else { 237 swrast->_DeferredTexture = GL_TRUE; 238 } 239 } 240 } 241 242 243 /** 244 * Update swrast->_FogColor and swrast->_FogEnable values. 245 */ 246 static void 247 _swrast_update_fog_state( struct gl_context *ctx ) 248 { 249 SWcontext *swrast = SWRAST_CONTEXT(ctx); 250 const struct gl_program *fp = ctx->FragmentProgram._Current; 251 252 assert(fp == NULL || fp->Target == GL_FRAGMENT_PROGRAM_ARB); 253 (void) fp; /* silence unused var warning */ 254 255 /* determine if fog is needed, and if so, which fog mode */ 256 swrast->_FogEnabled = (!_swrast_use_fragment_program(ctx) && 257 ctx->Fog.Enabled); 258 } 259 260 261 /** 262 * Update state for running fragment programs. Basically, load the 263 * program parameters with current state values. 264 */ 265 static void 266 _swrast_update_fragment_program(struct gl_context *ctx, GLbitfield newState) 267 { 268 if (!_swrast_use_fragment_program(ctx)) 269 return; 270 271 _mesa_load_state_parameters(ctx, 272 ctx->FragmentProgram._Current->Parameters); 273 } 274 275 276 /** 277 * See if we can do early diffuse+specular (primary+secondary) color 278 * add per vertex instead of per-fragment. 279 */ 280 static void 281 _swrast_update_specular_vertex_add(struct gl_context *ctx) 282 { 283 SWcontext *swrast = SWRAST_CONTEXT(ctx); 284 GLboolean separateSpecular = ctx->Fog.ColorSumEnabled || 285 (ctx->Light.Enabled && 286 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR); 287 288 swrast->SpecularVertexAdd = (separateSpecular 289 && ctx->Texture._MaxEnabledTexImageUnit == -1 290 && !_swrast_use_fragment_program(ctx) 291 && !ctx->ATIFragmentShader._Enabled); 292 } 293 294 295 #define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK | \ 296 _NEW_PROGRAM_CONSTANTS | \ 297 _NEW_TEXTURE | \ 298 _NEW_HINT | \ 299 _NEW_POLYGON ) 300 301 /* State referenced by _swrast_choose_triangle, _swrast_choose_line. 302 */ 303 #define _SWRAST_NEW_TRIANGLE (_SWRAST_NEW_DERIVED | \ 304 _NEW_RENDERMODE| \ 305 _NEW_POLYGON| \ 306 _NEW_DEPTH| \ 307 _NEW_STENCIL| \ 308 _NEW_COLOR| \ 309 _NEW_TEXTURE| \ 310 _SWRAST_NEW_RASTERMASK| \ 311 _NEW_LIGHT| \ 312 _NEW_FOG | \ 313 _MESA_NEW_SEPARATE_SPECULAR) 314 315 #define _SWRAST_NEW_LINE (_SWRAST_NEW_DERIVED | \ 316 _NEW_RENDERMODE| \ 317 _NEW_LINE| \ 318 _NEW_TEXTURE| \ 319 _NEW_LIGHT| \ 320 _NEW_FOG| \ 321 _NEW_DEPTH | \ 322 _MESA_NEW_SEPARATE_SPECULAR) 323 324 #define _SWRAST_NEW_POINT (_SWRAST_NEW_DERIVED | \ 325 _NEW_RENDERMODE | \ 326 _NEW_POINT | \ 327 _NEW_TEXTURE | \ 328 _NEW_LIGHT | \ 329 _NEW_FOG | \ 330 _MESA_NEW_SEPARATE_SPECULAR) 331 332 #define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE 333 334 #define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE 335 336 #define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR 337 338 339 340 /** 341 * Stub for swrast->Triangle to select a true triangle function 342 * after a state change. 343 */ 344 static void 345 _swrast_validate_triangle( struct gl_context *ctx, 346 const SWvertex *v0, 347 const SWvertex *v1, 348 const SWvertex *v2 ) 349 { 350 SWcontext *swrast = SWRAST_CONTEXT(ctx); 351 352 _swrast_validate_derived( ctx ); 353 swrast->choose_triangle( ctx ); 354 assert(swrast->Triangle); 355 356 if (swrast->SpecularVertexAdd) { 357 /* separate specular color, but no texture */ 358 swrast->SpecTriangle = swrast->Triangle; 359 swrast->Triangle = _swrast_add_spec_terms_triangle; 360 } 361 362 swrast->Triangle( ctx, v0, v1, v2 ); 363 } 364 365 /** 366 * Called via swrast->Line. Examine current GL state and choose a software 367 * line routine. Then call it. 368 */ 369 static void 370 _swrast_validate_line( struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1 ) 371 { 372 SWcontext *swrast = SWRAST_CONTEXT(ctx); 373 374 _swrast_validate_derived( ctx ); 375 swrast->choose_line( ctx ); 376 assert(swrast->Line); 377 378 if (swrast->SpecularVertexAdd) { 379 swrast->SpecLine = swrast->Line; 380 swrast->Line = _swrast_add_spec_terms_line; 381 } 382 383 swrast->Line( ctx, v0, v1 ); 384 } 385 386 /** 387 * Called via swrast->Point. Examine current GL state and choose a software 388 * point routine. Then call it. 389 */ 390 static void 391 _swrast_validate_point( struct gl_context *ctx, const SWvertex *v0 ) 392 { 393 SWcontext *swrast = SWRAST_CONTEXT(ctx); 394 395 _swrast_validate_derived( ctx ); 396 swrast->choose_point( ctx ); 397 398 if (swrast->SpecularVertexAdd) { 399 swrast->SpecPoint = swrast->Point; 400 swrast->Point = _swrast_add_spec_terms_point; 401 } 402 403 swrast->Point( ctx, v0 ); 404 } 405 406 407 /** 408 * Called via swrast->BlendFunc. Examine GL state to choose a blending 409 * function, then call it. 410 */ 411 static void 412 _swrast_validate_blend_func(struct gl_context *ctx, GLuint n, const GLubyte mask[], 413 GLvoid *src, const GLvoid *dst, 414 GLenum chanType ) 415 { 416 SWcontext *swrast = SWRAST_CONTEXT(ctx); 417 418 _swrast_validate_derived( ctx ); /* why is this needed? */ 419 _swrast_choose_blend_func( ctx, chanType ); 420 421 swrast->BlendFunc( ctx, n, mask, src, dst, chanType ); 422 } 423 424 static void 425 _swrast_sleep( struct gl_context *ctx, GLbitfield new_state ) 426 { 427 (void) ctx; (void) new_state; 428 } 429 430 431 static void 432 _swrast_invalidate_state( struct gl_context *ctx, GLbitfield new_state ) 433 { 434 SWcontext *swrast = SWRAST_CONTEXT(ctx); 435 GLuint i; 436 437 swrast->NewState |= new_state; 438 439 /* After 10 statechanges without any swrast functions being called, 440 * put the module to sleep. 441 */ 442 if (++swrast->StateChanges > 10) { 443 swrast->InvalidateState = _swrast_sleep; 444 swrast->NewState = ~0; 445 new_state = ~0; 446 } 447 448 if (new_state & swrast->InvalidateTriangleMask) 449 swrast->Triangle = _swrast_validate_triangle; 450 451 if (new_state & swrast->InvalidateLineMask) 452 swrast->Line = _swrast_validate_line; 453 454 if (new_state & swrast->InvalidatePointMask) 455 swrast->Point = _swrast_validate_point; 456 457 if (new_state & _SWRAST_NEW_BLEND_FUNC) 458 swrast->BlendFunc = _swrast_validate_blend_func; 459 460 if (new_state & _SWRAST_NEW_TEXTURE_SAMPLE_FUNC) 461 for (i = 0 ; i < ARRAY_SIZE(swrast->TextureSample); i++) 462 swrast->TextureSample[i] = NULL; 463 } 464 465 466 void 467 _swrast_update_texture_samplers(struct gl_context *ctx) 468 { 469 SWcontext *swrast = SWRAST_CONTEXT(ctx); 470 GLuint u; 471 472 if (!swrast) 473 return; /* pipe hack */ 474 475 for (u = 0; u < ARRAY_SIZE(swrast->TextureSample); u++) { 476 struct gl_texture_object *tObj = ctx->Texture.Unit[u]._Current; 477 /* Note: If tObj is NULL, the sample function will be a simple 478 * function that just returns opaque black (0,0,0,1). 479 */ 480 _mesa_update_fetch_functions(ctx, u); 481 swrast->TextureSample[u] = 482 _swrast_choose_texture_sample_func(ctx, tObj, 483 _mesa_get_samplerobj(ctx, u)); 484 } 485 } 486 487 488 /** 489 * Update swrast->_ActiveAttribs, swrast->_NumActiveAttribs, 490 * swrast->_ActiveAtttribMask. 491 */ 492 static void 493 _swrast_update_active_attribs(struct gl_context *ctx) 494 { 495 SWcontext *swrast = SWRAST_CONTEXT(ctx); 496 GLbitfield64 attribsMask; 497 498 /* 499 * Compute _ActiveAttribsMask = which fragment attributes are needed. 500 */ 501 if (_swrast_use_fragment_program(ctx)) { 502 /* fragment program/shader */ 503 attribsMask = ctx->FragmentProgram._Current->info.inputs_read; 504 attribsMask &= ~VARYING_BIT_POS; /* WPOS is always handled specially */ 505 } 506 else if (ctx->ATIFragmentShader._Enabled) { 507 attribsMask = VARYING_BIT_COL0 | VARYING_BIT_COL1 | 508 VARYING_BIT_FOGC | VARYING_BITS_TEX_ANY; 509 } 510 else { 511 /* fixed function */ 512 attribsMask = 0x0; 513 514 #if CHAN_TYPE == GL_FLOAT 515 attribsMask |= VARYING_BIT_COL0; 516 #endif 517 518 if (ctx->Fog.ColorSumEnabled || 519 (ctx->Light.Enabled && 520 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { 521 attribsMask |= VARYING_BIT_COL1; 522 } 523 524 if (swrast->_FogEnabled) 525 attribsMask |= VARYING_BIT_FOGC; 526 527 attribsMask |= (ctx->Texture._EnabledCoordUnits << VARYING_SLOT_TEX0); 528 } 529 530 swrast->_ActiveAttribMask = attribsMask; 531 532 /* Update _ActiveAttribs[] list */ 533 { 534 GLuint i, num = 0; 535 for (i = 0; i < VARYING_SLOT_MAX; i++) { 536 if (attribsMask & BITFIELD64_BIT(i)) { 537 swrast->_ActiveAttribs[num++] = i; 538 /* how should this attribute be interpolated? */ 539 if (i == VARYING_SLOT_COL0 || i == VARYING_SLOT_COL1) 540 swrast->_InterpMode[i] = ctx->Light.ShadeModel; 541 else 542 swrast->_InterpMode[i] = GL_SMOOTH; 543 } 544 } 545 swrast->_NumActiveAttribs = num; 546 } 547 } 548 549 550 void 551 _swrast_validate_derived( struct gl_context *ctx ) 552 { 553 SWcontext *swrast = SWRAST_CONTEXT(ctx); 554 555 if (swrast->NewState) { 556 if (swrast->NewState & _NEW_POLYGON) 557 _swrast_update_polygon( ctx ); 558 559 if (swrast->NewState & (_NEW_HINT | _NEW_PROGRAM)) 560 _swrast_update_fog_hint( ctx ); 561 562 if (swrast->NewState & _SWRAST_NEW_TEXTURE_ENV_MODE) 563 _swrast_update_texture_env( ctx ); 564 565 if (swrast->NewState & (_NEW_FOG | _NEW_PROGRAM)) 566 _swrast_update_fog_state( ctx ); 567 568 if (swrast->NewState & (_NEW_PROGRAM_CONSTANTS | _NEW_PROGRAM)) 569 _swrast_update_fragment_program( ctx, swrast->NewState ); 570 571 if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM)) { 572 _swrast_update_texture_samplers( ctx ); 573 } 574 575 if (swrast->NewState & (_NEW_COLOR | _NEW_PROGRAM)) 576 _swrast_update_deferred_texture(ctx); 577 578 if (swrast->NewState & _SWRAST_NEW_RASTERMASK) 579 _swrast_update_rasterflags( ctx ); 580 581 if (swrast->NewState & (_NEW_DEPTH | 582 _NEW_FOG | 583 _NEW_LIGHT | 584 _NEW_PROGRAM | 585 _NEW_TEXTURE)) 586 _swrast_update_active_attribs(ctx); 587 588 if (swrast->NewState & (_NEW_FOG | 589 _NEW_PROGRAM | 590 _NEW_LIGHT | 591 _NEW_TEXTURE)) 592 _swrast_update_specular_vertex_add(ctx); 593 594 swrast->NewState = 0; 595 swrast->StateChanges = 0; 596 swrast->InvalidateState = _swrast_invalidate_state; 597 } 598 } 599 600 #define SWRAST_DEBUG 0 601 602 /* Public entrypoints: See also s_bitmap.c, etc. 603 */ 604 void 605 _swrast_Quad( struct gl_context *ctx, 606 const SWvertex *v0, const SWvertex *v1, 607 const SWvertex *v2, const SWvertex *v3 ) 608 { 609 if (SWRAST_DEBUG) { 610 _mesa_debug(ctx, "_swrast_Quad\n"); 611 _swrast_print_vertex( ctx, v0 ); 612 _swrast_print_vertex( ctx, v1 ); 613 _swrast_print_vertex( ctx, v2 ); 614 _swrast_print_vertex( ctx, v3 ); 615 } 616 SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v3 ); 617 SWRAST_CONTEXT(ctx)->Triangle( ctx, v1, v2, v3 ); 618 } 619 620 void 621 _swrast_Triangle( struct gl_context *ctx, const SWvertex *v0, 622 const SWvertex *v1, const SWvertex *v2 ) 623 { 624 if (SWRAST_DEBUG) { 625 _mesa_debug(ctx, "_swrast_Triangle\n"); 626 _swrast_print_vertex( ctx, v0 ); 627 _swrast_print_vertex( ctx, v1 ); 628 _swrast_print_vertex( ctx, v2 ); 629 } 630 SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 ); 631 } 632 633 void 634 _swrast_Line( struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1 ) 635 { 636 if (SWRAST_DEBUG) { 637 _mesa_debug(ctx, "_swrast_Line\n"); 638 _swrast_print_vertex( ctx, v0 ); 639 _swrast_print_vertex( ctx, v1 ); 640 } 641 SWRAST_CONTEXT(ctx)->Line( ctx, v0, v1 ); 642 } 643 644 void 645 _swrast_Point( struct gl_context *ctx, const SWvertex *v0 ) 646 { 647 if (SWRAST_DEBUG) { 648 _mesa_debug(ctx, "_swrast_Point\n"); 649 _swrast_print_vertex( ctx, v0 ); 650 } 651 SWRAST_CONTEXT(ctx)->Point( ctx, v0 ); 652 } 653 654 void 655 _swrast_InvalidateState( struct gl_context *ctx, GLbitfield new_state ) 656 { 657 if (SWRAST_DEBUG) { 658 _mesa_debug(ctx, "_swrast_InvalidateState\n"); 659 } 660 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, new_state ); 661 } 662 663 void 664 _swrast_ResetLineStipple( struct gl_context *ctx ) 665 { 666 if (SWRAST_DEBUG) { 667 _mesa_debug(ctx, "_swrast_ResetLineStipple\n"); 668 } 669 SWRAST_CONTEXT(ctx)->StippleCounter = 0; 670 } 671 672 void 673 _swrast_SetFacing(struct gl_context *ctx, GLuint facing) 674 { 675 SWRAST_CONTEXT(ctx)->PointLineFacing = facing; 676 } 677 678 void 679 _swrast_allow_vertex_fog( struct gl_context *ctx, GLboolean value ) 680 { 681 if (SWRAST_DEBUG) { 682 _mesa_debug(ctx, "_swrast_allow_vertex_fog %d\n", value); 683 } 684 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); 685 SWRAST_CONTEXT(ctx)->AllowVertexFog = value; 686 } 687 688 void 689 _swrast_allow_pixel_fog( struct gl_context *ctx, GLboolean value ) 690 { 691 if (SWRAST_DEBUG) { 692 _mesa_debug(ctx, "_swrast_allow_pixel_fog %d\n", value); 693 } 694 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); 695 SWRAST_CONTEXT(ctx)->AllowPixelFog = value; 696 } 697 698 699 /** 700 * Initialize native program limits by copying the logical limits. 701 * See comments in init_program_limits() in context.c 702 */ 703 static void 704 init_program_native_limits(struct gl_program_constants *prog) 705 { 706 prog->MaxNativeInstructions = prog->MaxInstructions; 707 prog->MaxNativeAluInstructions = prog->MaxAluInstructions; 708 prog->MaxNativeTexInstructions = prog->MaxTexInstructions; 709 prog->MaxNativeTexIndirections = prog->MaxTexIndirections; 710 prog->MaxNativeAttribs = prog->MaxAttribs; 711 prog->MaxNativeTemps = prog->MaxTemps; 712 prog->MaxNativeAddressRegs = prog->MaxAddressRegs; 713 prog->MaxNativeParameters = prog->MaxParameters; 714 } 715 716 717 GLboolean 718 _swrast_CreateContext( struct gl_context *ctx ) 719 { 720 GLuint i; 721 SWcontext *swrast = calloc(1, sizeof(SWcontext)); 722 #ifdef _OPENMP 723 const GLuint maxThreads = omp_get_max_threads(); 724 #else 725 const GLuint maxThreads = 1; 726 #endif 727 728 assert(ctx->Const.MaxViewportWidth <= SWRAST_MAX_WIDTH); 729 assert(ctx->Const.MaxViewportHeight <= SWRAST_MAX_WIDTH); 730 731 assert(ctx->Const.MaxRenderbufferSize <= SWRAST_MAX_WIDTH); 732 733 /* make sure largest texture image is <= SWRAST_MAX_WIDTH in size */ 734 assert((1 << (ctx->Const.MaxTextureLevels - 1)) <= SWRAST_MAX_WIDTH); 735 assert((1 << (ctx->Const.MaxCubeTextureLevels - 1)) <= SWRAST_MAX_WIDTH); 736 assert((1 << (ctx->Const.Max3DTextureLevels - 1)) <= SWRAST_MAX_WIDTH); 737 738 assert(PROG_MAX_WIDTH == SWRAST_MAX_WIDTH); 739 740 if (SWRAST_DEBUG) { 741 _mesa_debug(ctx, "_swrast_CreateContext\n"); 742 } 743 744 if (!swrast) 745 return GL_FALSE; 746 747 swrast->NewState = ~0; 748 749 swrast->choose_point = _swrast_choose_point; 750 swrast->choose_line = _swrast_choose_line; 751 swrast->choose_triangle = _swrast_choose_triangle; 752 753 swrast->InvalidatePointMask = _SWRAST_NEW_POINT; 754 swrast->InvalidateLineMask = _SWRAST_NEW_LINE; 755 swrast->InvalidateTriangleMask = _SWRAST_NEW_TRIANGLE; 756 757 swrast->Point = _swrast_validate_point; 758 swrast->Line = _swrast_validate_line; 759 swrast->Triangle = _swrast_validate_triangle; 760 swrast->InvalidateState = _swrast_sleep; 761 swrast->BlendFunc = _swrast_validate_blend_func; 762 763 swrast->AllowVertexFog = GL_TRUE; 764 swrast->AllowPixelFog = GL_TRUE; 765 766 swrast->Driver.SpanRenderStart = _swrast_span_render_start; 767 swrast->Driver.SpanRenderFinish = _swrast_span_render_finish; 768 769 for (i = 0; i < ARRAY_SIZE(swrast->TextureSample); i++) 770 swrast->TextureSample[i] = NULL; 771 772 /* SpanArrays is global and shared by all SWspan instances. However, when 773 * using multiple threads, it is necessary to have one SpanArrays instance 774 * per thread. 775 */ 776 swrast->SpanArrays = malloc(maxThreads * sizeof(SWspanarrays)); 777 if (!swrast->SpanArrays) { 778 free(swrast); 779 return GL_FALSE; 780 } 781 for(i = 0; i < maxThreads; i++) { 782 swrast->SpanArrays[i].ChanType = CHAN_TYPE; 783 #if CHAN_TYPE == GL_UNSIGNED_BYTE 784 swrast->SpanArrays[i].rgba = swrast->SpanArrays[i].rgba8; 785 #elif CHAN_TYPE == GL_UNSIGNED_SHORT 786 swrast->SpanArrays[i].rgba = swrast->SpanArrays[i].rgba16; 787 #else 788 swrast->SpanArrays[i].rgba = swrast->SpanArrays[i].attribs[VARYING_SLOT_COL0]; 789 #endif 790 } 791 792 /* init point span buffer */ 793 swrast->PointSpan.primitive = GL_POINT; 794 swrast->PointSpan.end = 0; 795 swrast->PointSpan.facing = 0; 796 swrast->PointSpan.array = swrast->SpanArrays; 797 798 init_program_native_limits(&ctx->Const.Program[MESA_SHADER_VERTEX]); 799 init_program_native_limits(&ctx->Const.Program[MESA_SHADER_GEOMETRY]); 800 init_program_native_limits(&ctx->Const.Program[MESA_SHADER_FRAGMENT]); 801 802 ctx->swrast_context = swrast; 803 804 swrast->stencil_temp.buf1 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte)); 805 swrast->stencil_temp.buf2 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte)); 806 swrast->stencil_temp.buf3 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte)); 807 swrast->stencil_temp.buf4 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte)); 808 809 if (!swrast->stencil_temp.buf1 || 810 !swrast->stencil_temp.buf2 || 811 !swrast->stencil_temp.buf3 || 812 !swrast->stencil_temp.buf4) { 813 _swrast_DestroyContext(ctx); 814 return GL_FALSE; 815 } 816 817 return GL_TRUE; 818 } 819 820 void 821 _swrast_DestroyContext( struct gl_context *ctx ) 822 { 823 SWcontext *swrast = SWRAST_CONTEXT(ctx); 824 825 if (SWRAST_DEBUG) { 826 _mesa_debug(ctx, "_swrast_DestroyContext\n"); 827 } 828 829 free( swrast->SpanArrays ); 830 free( swrast->ZoomedArrays ); 831 free( swrast->TexelBuffer ); 832 833 free(swrast->stencil_temp.buf1); 834 free(swrast->stencil_temp.buf2); 835 free(swrast->stencil_temp.buf3); 836 free(swrast->stencil_temp.buf4); 837 838 free( swrast ); 839 840 ctx->swrast_context = 0; 841 } 842 843 844 struct swrast_device_driver * 845 _swrast_GetDeviceDriverReference( struct gl_context *ctx ) 846 { 847 SWcontext *swrast = SWRAST_CONTEXT(ctx); 848 return &swrast->Driver; 849 } 850 851 void 852 _swrast_flush( struct gl_context *ctx ) 853 { 854 SWcontext *swrast = SWRAST_CONTEXT(ctx); 855 /* flush any pending fragments from rendering points */ 856 if (swrast->PointSpan.end > 0) { 857 _swrast_write_rgba_span(ctx, &(swrast->PointSpan)); 858 swrast->PointSpan.end = 0; 859 } 860 } 861 862 void 863 _swrast_render_primitive( struct gl_context *ctx, GLenum prim ) 864 { 865 SWcontext *swrast = SWRAST_CONTEXT(ctx); 866 if (swrast->Primitive == GL_POINTS && prim != GL_POINTS) { 867 _swrast_flush(ctx); 868 } 869 swrast->Primitive = prim; 870 } 871 872 873 /** called via swrast->Driver.SpanRenderStart() */ 874 void 875 _swrast_span_render_start(struct gl_context *ctx) 876 { 877 _swrast_map_textures(ctx); 878 _swrast_map_renderbuffers(ctx); 879 } 880 881 882 /** called via swrast->Driver.SpanRenderFinish() */ 883 void 884 _swrast_span_render_finish(struct gl_context *ctx) 885 { 886 _swrast_unmap_textures(ctx); 887 _swrast_unmap_renderbuffers(ctx); 888 } 889 890 891 void 892 _swrast_render_start( struct gl_context *ctx ) 893 { 894 SWcontext *swrast = SWRAST_CONTEXT(ctx); 895 if (swrast->Driver.SpanRenderStart) 896 swrast->Driver.SpanRenderStart( ctx ); 897 swrast->PointSpan.end = 0; 898 } 899 900 void 901 _swrast_render_finish( struct gl_context *ctx ) 902 { 903 SWcontext *swrast = SWRAST_CONTEXT(ctx); 904 struct gl_query_object *query = ctx->Query.CurrentOcclusionObject; 905 906 _swrast_flush(ctx); 907 908 if (swrast->Driver.SpanRenderFinish) 909 swrast->Driver.SpanRenderFinish( ctx ); 910 911 if (query && (query->Target == GL_ANY_SAMPLES_PASSED || 912 query->Target == GL_ANY_SAMPLES_PASSED_CONSERVATIVE)) 913 query->Result = !!query->Result; 914 } 915 916 917 #define SWRAST_DEBUG_VERTICES 0 918 919 void 920 _swrast_print_vertex( struct gl_context *ctx, const SWvertex *v ) 921 { 922 GLuint i; 923 924 if (SWRAST_DEBUG_VERTICES) { 925 _mesa_debug(ctx, "win %f %f %f %f\n", 926 v->attrib[VARYING_SLOT_POS][0], 927 v->attrib[VARYING_SLOT_POS][1], 928 v->attrib[VARYING_SLOT_POS][2], 929 v->attrib[VARYING_SLOT_POS][3]); 930 931 for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) 932 if (ctx->Texture.Unit[i]._Current) 933 _mesa_debug(ctx, "texcoord[%d] %f %f %f %f\n", i, 934 v->attrib[VARYING_SLOT_TEX0 + i][0], 935 v->attrib[VARYING_SLOT_TEX0 + i][1], 936 v->attrib[VARYING_SLOT_TEX0 + i][2], 937 v->attrib[VARYING_SLOT_TEX0 + i][3]); 938 939 #if CHAN_TYPE == GL_FLOAT 940 _mesa_debug(ctx, "color %f %f %f %f\n", 941 v->color[0], v->color[1], v->color[2], v->color[3]); 942 #else 943 _mesa_debug(ctx, "color %d %d %d %d\n", 944 v->color[0], v->color[1], v->color[2], v->color[3]); 945 #endif 946 _mesa_debug(ctx, "spec %g %g %g %g\n", 947 v->attrib[VARYING_SLOT_COL1][0], 948 v->attrib[VARYING_SLOT_COL1][1], 949 v->attrib[VARYING_SLOT_COL1][2], 950 v->attrib[VARYING_SLOT_COL1][3]); 951 _mesa_debug(ctx, "fog %f\n", v->attrib[VARYING_SLOT_FOGC][0]); 952 _mesa_debug(ctx, "index %f\n", v->attrib[VARYING_SLOT_CI][0]); 953 _mesa_debug(ctx, "pointsize %f\n", v->pointSize); 954 _mesa_debug(ctx, "\n"); 955 } 956 } 957