s_context.c revision db79b5683cfc3f2ea3f9b0aca8c4d149bf9a63f7
1/* 2 * Mesa 3-D graphics library 3 * Version: 6.1 4 * 5 * Copyright (C) 1999-2004 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 "context.h" 31#include "colormac.h" 32#include "mtypes.h" 33#include "program.h" 34#include "texobj.h" 35#include "nvfragprog.h" 36 37#include "swrast.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_texture.h" 45 46 47/* 48 * Recompute the value of swrast->_RasterMask, etc. according to 49 * the current context. 50 */ 51static void 52_swrast_update_rasterflags( GLcontext *ctx ) 53{ 54 GLuint RasterMask = 0; 55 56 if (ctx->Color.AlphaEnabled) RasterMask |= ALPHATEST_BIT; 57 if (ctx->Color.BlendEnabled) RasterMask |= BLEND_BIT; 58 if (ctx->Depth.Test) RasterMask |= DEPTH_BIT; 59 if (ctx->Fog.Enabled) RasterMask |= FOG_BIT; 60 if (ctx->Scissor.Enabled) RasterMask |= CLIP_BIT; 61 if (ctx->Stencil.Enabled) RasterMask |= STENCIL_BIT; 62 if (ctx->Visual.rgbMode) { 63 const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); 64 if (colorMask != 0xffffffff) RasterMask |= MASKING_BIT; 65 if (ctx->Color._LogicOpEnabled) RasterMask |= LOGIC_OP_BIT; 66 if (ctx->Texture._EnabledUnits) RasterMask |= TEXTURE_BIT; 67 } 68 else { 69 if (ctx->Color.IndexMask != 0xffffffff) RasterMask |= MASKING_BIT; 70 if (ctx->Color.IndexLogicOpEnabled) RasterMask |= LOGIC_OP_BIT; 71 } 72 73 if (ctx->DrawBuffer->UseSoftwareAlphaBuffers 74 && ctx->Color.ColorMask[ACOMP] 75 && ctx->Color.DrawBuffer != GL_NONE) 76 RasterMask |= ALPHABUF_BIT; 77 78 if ( ctx->Viewport.X < 0 79 || ctx->Viewport.X + ctx->Viewport.Width > (GLint) ctx->DrawBuffer->Width 80 || ctx->Viewport.Y < 0 81 || ctx->Viewport.Y + ctx->Viewport.Height > (GLint) ctx->DrawBuffer->Height) { 82 RasterMask |= CLIP_BIT; 83 } 84 85 if (ctx->Depth.OcclusionTest || ctx->Occlusion.Active) 86 RasterMask |= OCCLUSION_BIT; 87 88 89 /* If we're not drawing to exactly one color buffer set the 90 * MULTI_DRAW_BIT flag. Also set it if we're drawing to no 91 * buffers or the RGBA or CI mask disables all writes. 92 */ 93 if (ctx->Color._DrawDestMask != FRONT_LEFT_BIT && 94 ctx->Color._DrawDestMask != BACK_LEFT_BIT && 95 ctx->Color._DrawDestMask != FRONT_RIGHT_BIT && 96 ctx->Color._DrawDestMask != BACK_RIGHT_BIT) { 97 /* more than one color buffer designated for writing (or zero buffers) */ 98 RasterMask |= MULTI_DRAW_BIT; 99 } 100 else if (ctx->Visual.rgbMode && *((GLuint *) ctx->Color.ColorMask) == 0) { 101 RasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */ 102 } 103 else if (!ctx->Visual.rgbMode && ctx->Color.IndexMask==0) { 104 RasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */ 105 } 106 107 if (ctx->FragmentProgram.Enabled) { 108 RasterMask |= FRAGPROG_BIT; 109 } 110 111 SWRAST_CONTEXT(ctx)->_RasterMask = RasterMask; 112} 113 114 115static void 116_swrast_update_polygon( GLcontext *ctx ) 117{ 118 GLfloat backface_sign = 1; 119 120 if (ctx->Polygon.CullFlag) { 121 backface_sign = 1; 122 switch(ctx->Polygon.CullFaceMode) { 123 case GL_BACK: 124 if(ctx->Polygon.FrontFace==GL_CCW) 125 backface_sign = -1; 126 break; 127 case GL_FRONT: 128 if(ctx->Polygon.FrontFace!=GL_CCW) 129 backface_sign = -1; 130 break; 131 default: 132 case GL_FRONT_AND_BACK: 133 backface_sign = 0; 134 break; 135 } 136 } 137 else { 138 backface_sign = 0; 139 } 140 141 SWRAST_CONTEXT(ctx)->_BackfaceSign = backface_sign; 142} 143 144 145static void 146_swrast_update_fog_hint( GLcontext *ctx ) 147{ 148 SWcontext *swrast = SWRAST_CONTEXT(ctx); 149 swrast->_PreferPixelFog = (!swrast->AllowVertexFog || 150 ctx->FragmentProgram.Enabled || 151 (ctx->Hint.Fog == GL_NICEST && 152 swrast->AllowPixelFog)); 153} 154 155 156 157/* 158 * Update the swrast->_AnyTextureCombine flag. 159 */ 160static void 161_swrast_update_texture_env( GLcontext *ctx ) 162{ 163 SWcontext *swrast = SWRAST_CONTEXT(ctx); 164 GLuint i; 165 swrast->_AnyTextureCombine = GL_FALSE; 166 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 167 if (ctx->Texture.Unit[i].EnvMode == GL_COMBINE_EXT || 168 ctx->Texture.Unit[i].EnvMode == GL_COMBINE4_NV) { 169 swrast->_AnyTextureCombine = GL_TRUE; 170 return; 171 } 172 } 173} 174 175 176/* 177 * Update swrast->_FogColor and swrast->_FogEnable values. 178 */ 179static void 180_swrast_update_fog_state( GLcontext *ctx ) 181{ 182 SWcontext *swrast = SWRAST_CONTEXT(ctx); 183 184 /* convert fog color to GLchan values */ 185 CLAMPED_FLOAT_TO_CHAN(swrast->_FogColor[RCOMP], ctx->Fog.Color[RCOMP]); 186 CLAMPED_FLOAT_TO_CHAN(swrast->_FogColor[GCOMP], ctx->Fog.Color[GCOMP]); 187 CLAMPED_FLOAT_TO_CHAN(swrast->_FogColor[BCOMP], ctx->Fog.Color[BCOMP]); 188 189 /* determine if fog is needed */ 190 swrast->_FogEnabled = GL_FALSE; 191 if (ctx->Fog.Enabled) { 192 swrast->_FogEnabled = GL_TRUE; 193 } 194 else if (ctx->FragmentProgram.Enabled && 195 ctx->FragmentProgram.Current->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { 196 const struct fragment_program *p; 197 p = (struct fragment_program *) ctx->FragmentProgram.Current; 198 if (p->FogOption != GL_NONE) { 199 swrast->_FogEnabled = GL_TRUE; 200 } 201 } 202} 203 204 205static void 206_swrast_update_fragment_program( GLcontext *ctx ) 207{ 208 if (ctx->FragmentProgram.Enabled) { 209 struct fragment_program *program = ctx->FragmentProgram.Current; 210 _mesa_load_state_parameters(ctx, program->Parameters); 211 } 212} 213 214 215 216#define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK | \ 217 _NEW_TEXTURE | \ 218 _NEW_HINT | \ 219 _NEW_POLYGON ) 220 221/* State referenced by _swrast_choose_triangle, _swrast_choose_line. 222 */ 223#define _SWRAST_NEW_TRIANGLE (_SWRAST_NEW_DERIVED | \ 224 _NEW_RENDERMODE| \ 225 _NEW_POLYGON| \ 226 _NEW_DEPTH| \ 227 _NEW_STENCIL| \ 228 _NEW_COLOR| \ 229 _NEW_TEXTURE| \ 230 _SWRAST_NEW_RASTERMASK| \ 231 _NEW_LIGHT| \ 232 _NEW_FOG | \ 233 _DD_NEW_SEPARATE_SPECULAR) 234 235#define _SWRAST_NEW_LINE (_SWRAST_NEW_DERIVED | \ 236 _NEW_RENDERMODE| \ 237 _NEW_LINE| \ 238 _NEW_TEXTURE| \ 239 _NEW_LIGHT| \ 240 _NEW_FOG| \ 241 _NEW_DEPTH | \ 242 _DD_NEW_SEPARATE_SPECULAR) 243 244#define _SWRAST_NEW_POINT (_SWRAST_NEW_DERIVED | \ 245 _NEW_RENDERMODE | \ 246 _NEW_POINT | \ 247 _NEW_TEXTURE | \ 248 _NEW_LIGHT | \ 249 _NEW_FOG | \ 250 _DD_NEW_SEPARATE_SPECULAR) 251 252#define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE 253 254#define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE 255 256#define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR 257 258 259 260/* Stub for swrast->Triangle to select a true triangle function 261 * after a state change. 262 */ 263static void 264_swrast_validate_triangle( GLcontext *ctx, 265 const SWvertex *v0, 266 const SWvertex *v1, 267 const SWvertex *v2 ) 268{ 269 SWcontext *swrast = SWRAST_CONTEXT(ctx); 270 271 _swrast_validate_derived( ctx ); 272 swrast->choose_triangle( ctx ); 273 274 if (ctx->Texture._EnabledUnits == 0 275 && NEED_SECONDARY_COLOR(ctx) 276 && !ctx->FragmentProgram.Enabled) { 277 /* separate specular color, but no texture */ 278 swrast->SpecTriangle = swrast->Triangle; 279 swrast->Triangle = _swrast_add_spec_terms_triangle; 280 } 281 282 swrast->Triangle( ctx, v0, v1, v2 ); 283} 284 285static void 286_swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) 287{ 288 SWcontext *swrast = SWRAST_CONTEXT(ctx); 289 290 _swrast_validate_derived( ctx ); 291 swrast->choose_line( ctx ); 292 293 if (ctx->Texture._EnabledUnits == 0 294 && NEED_SECONDARY_COLOR(ctx) 295 && !ctx->FragmentProgram.Enabled) { 296 swrast->SpecLine = swrast->Line; 297 swrast->Line = _swrast_add_spec_terms_line; 298 } 299 300 301 swrast->Line( ctx, v0, v1 ); 302} 303 304static void 305_swrast_validate_point( GLcontext *ctx, const SWvertex *v0 ) 306{ 307 SWcontext *swrast = SWRAST_CONTEXT(ctx); 308 309 _swrast_validate_derived( ctx ); 310 swrast->choose_point( ctx ); 311 312 if (ctx->Texture._EnabledUnits == 0 313 && NEED_SECONDARY_COLOR(ctx) 314 && !ctx->FragmentProgram.Enabled) { 315 swrast->SpecPoint = swrast->Point; 316 swrast->Point = _swrast_add_spec_terms_point; 317 } 318 319 swrast->Point( ctx, v0 ); 320} 321 322 323static void _ASMAPI 324_swrast_validate_blend_func( GLcontext *ctx, GLuint n, 325 const GLubyte mask[], 326 GLchan src[][4], 327 CONST GLchan dst[][4] ) 328{ 329 SWcontext *swrast = SWRAST_CONTEXT(ctx); 330 331 _swrast_validate_derived( ctx ); 332 _swrast_choose_blend_func( ctx ); 333 334 swrast->BlendFunc( ctx, n, mask, src, dst ); 335} 336 337 338static void 339_swrast_validate_texture_sample( GLcontext *ctx, GLuint texUnit, 340 const struct gl_texture_object *tObj, 341 GLuint n, const GLfloat texcoords[][4], 342 const GLfloat lambda[], GLchan rgba[][4] ) 343{ 344 SWcontext *swrast = SWRAST_CONTEXT(ctx); 345 346 _swrast_validate_derived( ctx ); 347 348 /* Compute min/mag filter threshold */ 349 if (tObj->MinFilter != tObj->MagFilter) { 350 if (tObj->MagFilter == GL_LINEAR 351 && (tObj->MinFilter == GL_NEAREST_MIPMAP_NEAREST || 352 tObj->MinFilter == GL_NEAREST_MIPMAP_LINEAR)) { 353 swrast->_MinMagThresh[texUnit] = 0.5F; 354 } 355 else { 356 swrast->_MinMagThresh[texUnit] = 0.0F; 357 } 358 } 359 360 swrast->TextureSample[texUnit] = 361 _swrast_choose_texture_sample_func( ctx, tObj ); 362 363 swrast->TextureSample[texUnit]( ctx, texUnit, tObj, n, texcoords, 364 lambda, rgba ); 365} 366 367 368static void 369_swrast_sleep( GLcontext *ctx, GLuint new_state ) 370{ 371} 372 373 374static void 375_swrast_invalidate_state( GLcontext *ctx, GLuint new_state ) 376{ 377 SWcontext *swrast = SWRAST_CONTEXT(ctx); 378 GLuint i; 379 380 swrast->NewState |= new_state; 381 382 /* After 10 statechanges without any swrast functions being called, 383 * put the module to sleep. 384 */ 385 if (++swrast->StateChanges > 10) { 386 swrast->InvalidateState = _swrast_sleep; 387 swrast->NewState = ~0; 388 new_state = ~0; 389 } 390 391 if (new_state & swrast->invalidate_triangle) 392 swrast->Triangle = _swrast_validate_triangle; 393 394 if (new_state & swrast->invalidate_line) 395 swrast->Line = _swrast_validate_line; 396 397 if (new_state & swrast->invalidate_point) 398 swrast->Point = _swrast_validate_point; 399 400 if (new_state & _SWRAST_NEW_BLEND_FUNC) 401 swrast->BlendFunc = _swrast_validate_blend_func; 402 403 if (new_state & _SWRAST_NEW_TEXTURE_SAMPLE_FUNC) 404 for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) 405 swrast->TextureSample[i] = _swrast_validate_texture_sample; 406 407 if (ctx->Visual.rgbMode) { 408 ASSERT(swrast->Driver.WriteRGBASpan); 409 ASSERT(swrast->Driver.WriteRGBSpan); 410 ASSERT(swrast->Driver.WriteMonoRGBASpan); 411 ASSERT(swrast->Driver.WriteRGBAPixels); 412 ASSERT(swrast->Driver.WriteMonoRGBAPixels); 413 ASSERT(swrast->Driver.ReadRGBASpan); 414 ASSERT(swrast->Driver.ReadRGBAPixels); 415 } 416 else { 417 ASSERT(swrast->Driver.WriteCI32Span); 418 ASSERT(swrast->Driver.WriteCI8Span); 419 ASSERT(swrast->Driver.WriteMonoCISpan); 420 ASSERT(swrast->Driver.WriteCI32Pixels); 421 ASSERT(swrast->Driver.WriteMonoCIPixels); 422 ASSERT(swrast->Driver.ReadCI32Span); 423 ASSERT(swrast->Driver.ReadCI32Pixels); 424 } 425} 426 427 428void 429_swrast_validate_derived( GLcontext *ctx ) 430{ 431 SWcontext *swrast = SWRAST_CONTEXT(ctx); 432 433 if (swrast->NewState) { 434 if (swrast->NewState & _SWRAST_NEW_RASTERMASK) 435 _swrast_update_rasterflags( ctx ); 436 437 if (swrast->NewState & _NEW_POLYGON) 438 _swrast_update_polygon( ctx ); 439 440 if (swrast->NewState & (_NEW_HINT | _NEW_PROGRAM)) 441 _swrast_update_fog_hint( ctx ); 442 443 if (swrast->NewState & _SWRAST_NEW_TEXTURE_ENV_MODE) 444 _swrast_update_texture_env( ctx ); 445 446 if (swrast->NewState & _NEW_FOG) 447 _swrast_update_fog_state( ctx ); 448 449 if (swrast->NewState & _NEW_PROGRAM) 450 _swrast_update_fragment_program( ctx ); 451 452 swrast->NewState = 0; 453 swrast->StateChanges = 0; 454 swrast->InvalidateState = _swrast_invalidate_state; 455 } 456} 457 458#define SWRAST_DEBUG 0 459 460/* Public entrypoints: See also s_accum.c, s_bitmap.c, etc. 461 */ 462void 463_swrast_Quad( GLcontext *ctx, 464 const SWvertex *v0, const SWvertex *v1, 465 const SWvertex *v2, const SWvertex *v3 ) 466{ 467 if (SWRAST_DEBUG) { 468 _mesa_debug(ctx, "_swrast_Quad\n"); 469 _swrast_print_vertex( ctx, v0 ); 470 _swrast_print_vertex( ctx, v1 ); 471 _swrast_print_vertex( ctx, v2 ); 472 _swrast_print_vertex( ctx, v3 ); 473 } 474 SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v3 ); 475 SWRAST_CONTEXT(ctx)->Triangle( ctx, v1, v2, v3 ); 476} 477 478void 479_swrast_Triangle( GLcontext *ctx, const SWvertex *v0, 480 const SWvertex *v1, const SWvertex *v2 ) 481{ 482 if (SWRAST_DEBUG) { 483 _mesa_debug(ctx, "_swrast_Triangle\n"); 484 _swrast_print_vertex( ctx, v0 ); 485 _swrast_print_vertex( ctx, v1 ); 486 _swrast_print_vertex( ctx, v2 ); 487 } 488 SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 ); 489} 490 491void 492_swrast_Line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) 493{ 494 if (SWRAST_DEBUG) { 495 _mesa_debug(ctx, "_swrast_Line\n"); 496 _swrast_print_vertex( ctx, v0 ); 497 _swrast_print_vertex( ctx, v1 ); 498 } 499 SWRAST_CONTEXT(ctx)->Line( ctx, v0, v1 ); 500} 501 502void 503_swrast_Point( GLcontext *ctx, const SWvertex *v0 ) 504{ 505 if (SWRAST_DEBUG) { 506 _mesa_debug(ctx, "_swrast_Point\n"); 507 _swrast_print_vertex( ctx, v0 ); 508 } 509 SWRAST_CONTEXT(ctx)->Point( ctx, v0 ); 510} 511 512void 513_swrast_InvalidateState( GLcontext *ctx, GLuint new_state ) 514{ 515 if (SWRAST_DEBUG) { 516 _mesa_debug(ctx, "_swrast_InvalidateState\n"); 517 } 518 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, new_state ); 519} 520 521void 522_swrast_ResetLineStipple( GLcontext *ctx ) 523{ 524 if (SWRAST_DEBUG) { 525 _mesa_debug(ctx, "_swrast_ResetLineStipple\n"); 526 } 527 SWRAST_CONTEXT(ctx)->StippleCounter = 0; 528} 529 530void 531_swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value ) 532{ 533 if (SWRAST_DEBUG) { 534 _mesa_debug(ctx, "_swrast_allow_vertex_fog %d\n", value); 535 } 536 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); 537 SWRAST_CONTEXT(ctx)->AllowVertexFog = value; 538} 539 540void 541_swrast_allow_pixel_fog( GLcontext *ctx, GLboolean value ) 542{ 543 if (SWRAST_DEBUG) { 544 _mesa_debug(ctx, "_swrast_allow_pixel_fog %d\n", value); 545 } 546 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); 547 SWRAST_CONTEXT(ctx)->AllowPixelFog = value; 548} 549 550 551GLboolean 552_swrast_CreateContext( GLcontext *ctx ) 553{ 554 GLuint i; 555 SWcontext *swrast = (SWcontext *)CALLOC(sizeof(SWcontext)); 556 557 if (SWRAST_DEBUG) { 558 _mesa_debug(ctx, "_swrast_CreateContext\n"); 559 } 560 561 if (!swrast) 562 return GL_FALSE; 563 564 swrast->NewState = ~0; 565 566 swrast->choose_point = _swrast_choose_point; 567 swrast->choose_line = _swrast_choose_line; 568 swrast->choose_triangle = _swrast_choose_triangle; 569 570 swrast->invalidate_point = _SWRAST_NEW_POINT; 571 swrast->invalidate_line = _SWRAST_NEW_LINE; 572 swrast->invalidate_triangle = _SWRAST_NEW_TRIANGLE; 573 574 swrast->Point = _swrast_validate_point; 575 swrast->Line = _swrast_validate_line; 576 swrast->Triangle = _swrast_validate_triangle; 577 swrast->InvalidateState = _swrast_sleep; 578 swrast->BlendFunc = _swrast_validate_blend_func; 579 580 swrast->AllowVertexFog = GL_TRUE; 581 swrast->AllowPixelFog = GL_TRUE; 582 583 if (ctx->Visual.doubleBufferMode) 584 swrast->CurrentBuffer = BACK_LEFT_BIT; 585 else 586 swrast->CurrentBuffer = FRONT_LEFT_BIT; 587 588 /* Optimized Accum buffer */ 589 swrast->_IntegerAccumMode = GL_TRUE; 590 swrast->_IntegerAccumScaler = 0.0; 591 592 for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) 593 swrast->TextureSample[i] = _swrast_validate_texture_sample; 594 595 swrast->SpanArrays = MALLOC_STRUCT(span_arrays); 596 if (!swrast->SpanArrays) { 597 FREE(swrast); 598 return GL_FALSE; 599 } 600 601 /* init point span buffer */ 602 swrast->PointSpan.primitive = GL_POINT; 603 swrast->PointSpan.start = 0; 604 swrast->PointSpan.end = 0; 605 swrast->PointSpan.facing = 0; 606 swrast->PointSpan.array = swrast->SpanArrays; 607 608 assert(ctx->Const.MaxTextureUnits > 0); 609 assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_UNITS); 610 611 swrast->TexelBuffer = (GLchan *) MALLOC(ctx->Const.MaxTextureUnits * 612 MAX_WIDTH * 4 * sizeof(GLchan)); 613 if (!swrast->TexelBuffer) { 614 FREE(swrast->SpanArrays); 615 FREE(swrast); 616 return GL_FALSE; 617 } 618 619 ctx->swrast_context = swrast; 620 621 return GL_TRUE; 622} 623 624void 625_swrast_DestroyContext( GLcontext *ctx ) 626{ 627 SWcontext *swrast = SWRAST_CONTEXT(ctx); 628 629 if (SWRAST_DEBUG) { 630 _mesa_debug(ctx, "_swrast_DestroyContext\n"); 631 } 632 633 FREE( swrast->SpanArrays ); 634 FREE( swrast->TexelBuffer ); 635 FREE( swrast ); 636 637 ctx->swrast_context = 0; 638} 639 640 641struct swrast_device_driver * 642_swrast_GetDeviceDriverReference( GLcontext *ctx ) 643{ 644 SWcontext *swrast = SWRAST_CONTEXT(ctx); 645 return &swrast->Driver; 646} 647 648void 649_swrast_flush( GLcontext *ctx ) 650{ 651 SWcontext *swrast = SWRAST_CONTEXT(ctx); 652 /* flush any pending fragments from rendering points */ 653 if (swrast->PointSpan.end > 0) { 654 if (ctx->Visual.rgbMode) { 655 if (ctx->Texture._EnabledCoordUnits) 656 _swrast_write_texture_span(ctx, &(swrast->PointSpan)); 657 else 658 _swrast_write_rgba_span(ctx, &(swrast->PointSpan)); 659 } 660 else { 661 _swrast_write_index_span(ctx, &(swrast->PointSpan)); 662 } 663 swrast->PointSpan.end = 0; 664 } 665} 666 667void 668_swrast_render_primitive( GLcontext *ctx, GLenum prim ) 669{ 670 SWcontext *swrast = SWRAST_CONTEXT(ctx); 671 if (swrast->Primitive == GL_POINTS && prim != GL_POINTS) { 672 _swrast_flush(ctx); 673 } 674 swrast->Primitive = prim; 675} 676 677 678void 679_swrast_render_start( GLcontext *ctx ) 680{ 681 SWcontext *swrast = SWRAST_CONTEXT(ctx); 682 if (swrast->Driver.SpanRenderStart) 683 swrast->Driver.SpanRenderStart( ctx ); 684 swrast->PointSpan.end = 0; 685} 686 687void 688_swrast_render_finish( GLcontext *ctx ) 689{ 690 SWcontext *swrast = SWRAST_CONTEXT(ctx); 691 if (swrast->Driver.SpanRenderFinish) 692 swrast->Driver.SpanRenderFinish( ctx ); 693 694 _swrast_flush(ctx); 695} 696 697 698#define SWRAST_DEBUG_VERTICES 0 699 700void 701_swrast_print_vertex( GLcontext *ctx, const SWvertex *v ) 702{ 703 GLuint i; 704 705 if (SWRAST_DEBUG_VERTICES) { 706 _mesa_debug(ctx, "win %f %f %f %f\n", 707 v->win[0], v->win[1], v->win[2], v->win[3]); 708 709 for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) 710 if (ctx->Texture.Unit[i]._ReallyEnabled) 711 _mesa_debug(ctx, "texcoord[%d] %f %f %f %f\n", i, 712 v->texcoord[i][0], v->texcoord[i][1], 713 v->texcoord[i][2], v->texcoord[i][3]); 714 715#if CHAN_TYPE == GL_FLOAT 716 _mesa_debug(ctx, "color %f %f %f %f\n", 717 v->color[0], v->color[1], v->color[2], v->color[3]); 718 _mesa_debug(ctx, "spec %f %f %f %f\n", 719 v->specular[0], v->specular[1], 720 v->specular[2], v->specular[3]); 721#else 722 _mesa_debug(ctx, "color %d %d %d %d\n", 723 v->color[0], v->color[1], v->color[2], v->color[3]); 724 _mesa_debug(ctx, "spec %d %d %d %d\n", 725 v->specular[0], v->specular[1], 726 v->specular[2], v->specular[3]); 727#endif 728 _mesa_debug(ctx, "fog %f\n", v->fog); 729 _mesa_debug(ctx, "index %d\n", v->index); 730 _mesa_debug(ctx, "pointsize %f\n", v->pointSize); 731 _mesa_debug(ctx, "\n"); 732 } 733} 734