s_context.c revision 9927f1978da8530416f699d084dda099720e43e6
1/* $Id: s_context.c,v 1.27 2002/01/10 16:54:28 brianp Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 4.1 6 * 7 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included 17 * in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 * Authors: 27 * Keith Whitwell <keithw@valinux.com> 28 */ 29 30#include "glheader.h" 31#include "mtypes.h" 32#include "mem.h" 33 34#include "s_pb.h" 35#include "s_points.h" 36#include "s_lines.h" 37#include "s_triangle.h" 38#include "s_blend.h" 39#include "s_context.h" 40#include "s_texture.h" 41 42 43 44 45 46/* 47 * Recompute the value of swrast->_RasterMask, etc. according to 48 * the current context. 49 */ 50static void 51_swrast_update_rasterflags( GLcontext *ctx ) 52{ 53 GLuint RasterMask = 0; 54 55 if (ctx->Color.AlphaEnabled) RasterMask |= ALPHATEST_BIT; 56 if (ctx->Color.BlendEnabled) RasterMask |= BLEND_BIT; 57 if (ctx->Depth.Test) RasterMask |= DEPTH_BIT; 58 if (ctx->Fog.Enabled) RasterMask |= FOG_BIT; 59 if (ctx->Scissor.Enabled) RasterMask |= SCISSOR_BIT; 60 if (ctx->Stencil.Enabled) RasterMask |= STENCIL_BIT; 61 if (ctx->Visual.rgbMode) { 62 const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); 63 if (colorMask != 0xffffffff) RasterMask |= MASKING_BIT; 64 if (ctx->Color.ColorLogicOpEnabled) RasterMask |= LOGIC_OP_BIT; 65 if (ctx->Texture._ReallyEnabled) RasterMask |= TEXTURE_BIT; 66 } 67 else { 68 if (ctx->Color.IndexMask != 0xffffffff) RasterMask |= MASKING_BIT; 69 if (ctx->Color.IndexLogicOpEnabled) RasterMask |= LOGIC_OP_BIT; 70 } 71 72 if (ctx->DrawBuffer->UseSoftwareAlphaBuffers 73 && ctx->Color.ColorMask[ACOMP] 74 && ctx->Color.DrawBuffer != GL_NONE) 75 RasterMask |= ALPHABUF_BIT; 76 77 if ( ctx->Viewport.X < 0 78 || ctx->Viewport.X + ctx->Viewport.Width > ctx->DrawBuffer->Width 79 || ctx->Viewport.Y < 0 80 || ctx->Viewport.Y + ctx->Viewport.Height > ctx->DrawBuffer->Height) { 81 RasterMask |= WINCLIP_BIT; 82 } 83 84 if (ctx->Depth.OcclusionTest) 85 RasterMask |= OCCLUSION_BIT; 86 87 88 /* If we're not drawing to exactly one color buffer set the 89 * MULTI_DRAW_BIT flag. Also set it if we're drawing to no 90 * buffers or the RGBA or CI mask disables all writes. 91 */ 92 if (ctx->Color.MultiDrawBuffer) { 93 RasterMask |= MULTI_DRAW_BIT; 94 } 95 else if (ctx->Color.DrawBuffer==GL_NONE) { 96 RasterMask |= MULTI_DRAW_BIT; 97 } 98 else if (ctx->Visual.rgbMode && *((GLuint *) ctx->Color.ColorMask) == 0) { 99 RasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */ 100 } 101 else if (!ctx->Visual.rgbMode && ctx->Color.IndexMask==0) { 102 RasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */ 103 } 104 105 SWRAST_CONTEXT(ctx)->_RasterMask = RasterMask; 106} 107 108 109static void 110_swrast_update_polygon( GLcontext *ctx ) 111{ 112 GLfloat backface_sign = 1; 113 114 if (ctx->Polygon.CullFlag) { 115 backface_sign = 1; 116 switch(ctx->Polygon.CullFaceMode) { 117 case GL_BACK: 118 if(ctx->Polygon.FrontFace==GL_CCW) 119 backface_sign = -1; 120 break; 121 case GL_FRONT: 122 if(ctx->Polygon.FrontFace!=GL_CCW) 123 backface_sign = -1; 124 break; 125 default: 126 case GL_FRONT_AND_BACK: 127 backface_sign = 0; 128 break; 129 } 130 } 131 else { 132 backface_sign = 0; 133 } 134 135 SWRAST_CONTEXT(ctx)->_backface_sign = backface_sign; 136} 137 138 139static void 140_swrast_update_hint( GLcontext *ctx ) 141{ 142 SWcontext *swrast = SWRAST_CONTEXT(ctx); 143 swrast->_PreferPixelFog = (!swrast->AllowVertexFog || 144 (ctx->Hint.Fog == GL_NICEST && 145 swrast->AllowPixelFog)); 146} 147 148#define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK | \ 149 _NEW_TEXTURE | \ 150 _NEW_HINT | \ 151 _NEW_POLYGON ) 152 153/* State referenced by _swrast_choose_triangle, _swrast_choose_line. 154 */ 155#define _SWRAST_NEW_TRIANGLE (_SWRAST_NEW_DERIVED | \ 156 _NEW_RENDERMODE| \ 157 _NEW_POLYGON| \ 158 _NEW_DEPTH| \ 159 _NEW_STENCIL| \ 160 _NEW_COLOR| \ 161 _NEW_TEXTURE| \ 162 _SWRAST_NEW_RASTERMASK| \ 163 _NEW_LIGHT| \ 164 _NEW_FOG | \ 165 _DD_NEW_SEPARATE_SPECULAR) 166 167#define _SWRAST_NEW_LINE (_SWRAST_NEW_DERIVED | \ 168 _NEW_RENDERMODE| \ 169 _NEW_LINE| \ 170 _NEW_TEXTURE| \ 171 _NEW_LIGHT| \ 172 _NEW_FOG| \ 173 _NEW_DEPTH | \ 174 _DD_NEW_SEPARATE_SPECULAR) 175 176#define _SWRAST_NEW_POINT (_SWRAST_NEW_DERIVED | \ 177 _NEW_RENDERMODE | \ 178 _NEW_POINT | \ 179 _NEW_TEXTURE | \ 180 _NEW_LIGHT | \ 181 _NEW_FOG | \ 182 _DD_NEW_SEPARATE_SPECULAR) 183 184#define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE 185 186#define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR 187 188 189 190/* Stub for swrast->Triangle to select a true triangle function 191 * after a state change. 192 */ 193static void 194_swrast_validate_triangle( GLcontext *ctx, 195 const SWvertex *v0, 196 const SWvertex *v1, 197 const SWvertex *v2 ) 198{ 199 SWcontext *swrast = SWRAST_CONTEXT(ctx); 200 201 _swrast_validate_derived( ctx ); 202 swrast->choose_triangle( ctx ); 203 204 if ((ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) && 205 !ctx->Texture._ReallyEnabled) { 206 swrast->SpecTriangle = swrast->Triangle; 207 swrast->Triangle = _swrast_add_spec_terms_triangle; 208 } 209 210 swrast->Triangle( ctx, v0, v1, v2 ); 211} 212 213static void 214_swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) 215{ 216 SWcontext *swrast = SWRAST_CONTEXT(ctx); 217 218 _swrast_validate_derived( ctx ); 219 swrast->choose_line( ctx ); 220 221 if ((ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) && 222 !ctx->Texture._ReallyEnabled) { 223 swrast->SpecLine = swrast->Line; 224 swrast->Line = _swrast_add_spec_terms_line; 225 } 226 227 228 swrast->Line( ctx, v0, v1 ); 229} 230 231static void 232_swrast_validate_point( GLcontext *ctx, const SWvertex *v0 ) 233{ 234 SWcontext *swrast = SWRAST_CONTEXT(ctx); 235 236 _swrast_validate_derived( ctx ); 237 swrast->choose_point( ctx ); 238 239 if ((ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) && 240 !ctx->Texture._ReallyEnabled) { 241 swrast->SpecPoint = swrast->Point; 242 swrast->Point = _swrast_add_spec_terms_point; 243 } 244 245 swrast->Point( ctx, v0 ); 246} 247 248static void 249_swrast_validate_blend_func( GLcontext *ctx, GLuint n, 250 const GLubyte mask[], 251 GLchan src[][4], 252 CONST GLchan dst[][4] ) 253{ 254 SWcontext *swrast = SWRAST_CONTEXT(ctx); 255 256 _swrast_validate_derived( ctx ); 257 _swrast_choose_blend_func( ctx ); 258 259 swrast->BlendFunc( ctx, n, mask, src, dst ); 260} 261 262 263static void 264_swrast_validate_texture_sample( GLcontext *ctx, GLuint texUnit, 265 const struct gl_texture_object *tObj, 266 GLuint n, GLfloat texcoords[][4], 267 const GLfloat lambda[], GLchan rgba[][4] ) 268{ 269 SWcontext *swrast = SWRAST_CONTEXT(ctx); 270 271 _swrast_validate_derived( ctx ); 272 _swrast_choose_texture_sample_func( ctx, texUnit, tObj ); 273 274 swrast->TextureSample[texUnit]( ctx, texUnit, tObj, n, texcoords, 275 lambda, rgba ); 276} 277 278 279static void 280_swrast_sleep( GLcontext *ctx, GLuint new_state ) 281{ 282} 283 284 285static void 286_swrast_invalidate_state( GLcontext *ctx, GLuint new_state ) 287{ 288 SWcontext *swrast = SWRAST_CONTEXT(ctx); 289 GLuint i; 290 291 swrast->NewState |= new_state; 292 293 /* After 10 statechanges without any swrast functions being called, 294 * put the module to sleep. 295 */ 296 if (++swrast->StateChanges > 10) { 297 swrast->InvalidateState = _swrast_sleep; 298 swrast->NewState = ~0; 299 new_state = ~0; 300 } 301 302 if (new_state & swrast->invalidate_triangle) 303 swrast->Triangle = _swrast_validate_triangle; 304 305 if (new_state & swrast->invalidate_line) 306 swrast->Line = _swrast_validate_line; 307 308 if (new_state & swrast->invalidate_point) 309 swrast->Point = _swrast_validate_point; 310 311 if (new_state & _SWRAST_NEW_BLEND_FUNC) 312 swrast->BlendFunc = _swrast_validate_blend_func; 313 314 if (new_state & _SWRAST_NEW_TEXTURE_SAMPLE_FUNC) 315 for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) 316 swrast->TextureSample[i] = _swrast_validate_texture_sample; 317 318 319 if (ctx->Visual.rgbMode) { 320 ASSERT(swrast->Driver.WriteRGBASpan); 321 ASSERT(swrast->Driver.WriteRGBSpan); 322 ASSERT(swrast->Driver.WriteMonoRGBASpan); 323 ASSERT(swrast->Driver.WriteRGBAPixels); 324 ASSERT(swrast->Driver.WriteMonoRGBAPixels); 325 ASSERT(swrast->Driver.ReadRGBASpan); 326 ASSERT(swrast->Driver.ReadRGBAPixels); 327 } 328 else { 329 ASSERT(swrast->Driver.WriteCI32Span); 330 ASSERT(swrast->Driver.WriteCI8Span); 331 ASSERT(swrast->Driver.WriteMonoCISpan); 332 ASSERT(swrast->Driver.WriteCI32Pixels); 333 ASSERT(swrast->Driver.WriteMonoCIPixels); 334 ASSERT(swrast->Driver.ReadCI32Span); 335 ASSERT(swrast->Driver.ReadCI32Pixels); 336 } 337 338} 339 340 341 342void 343_swrast_validate_derived( GLcontext *ctx ) 344{ 345 SWcontext *swrast = SWRAST_CONTEXT(ctx); 346 347 if (swrast->NewState) 348 { 349 if (swrast->NewState & _SWRAST_NEW_RASTERMASK) 350 _swrast_update_rasterflags( ctx ); 351 352 if (swrast->NewState & _NEW_POLYGON) 353 _swrast_update_polygon( ctx ); 354 355 if (swrast->NewState & _NEW_HINT) 356 _swrast_update_hint( ctx ); 357 358 swrast->NewState = 0; 359 swrast->StateChanges = 0; 360 swrast->InvalidateState = _swrast_invalidate_state; 361 } 362} 363 364#define SWRAST_DEBUG 0 365 366/* Public entrypoints: See also s_accum.c, s_bitmap.c, etc. 367 */ 368void 369_swrast_Quad( GLcontext *ctx, 370 const SWvertex *v0, const SWvertex *v1, 371 const SWvertex *v2, const SWvertex *v3 ) 372{ 373 if (SWRAST_DEBUG) { 374 fprintf(stderr, "_swrast_Quad\n"); 375 _swrast_print_vertex( ctx, v0 ); 376 _swrast_print_vertex( ctx, v1 ); 377 _swrast_print_vertex( ctx, v2 ); 378 _swrast_print_vertex( ctx, v3 ); 379 } 380 SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v3 ); 381 SWRAST_CONTEXT(ctx)->Triangle( ctx, v1, v2, v3 ); 382} 383 384void 385_swrast_Triangle( GLcontext *ctx, const SWvertex *v0, 386 const SWvertex *v1, const SWvertex *v2 ) 387{ 388 if (SWRAST_DEBUG) { 389 fprintf(stderr, "_swrast_Triangle\n"); 390 _swrast_print_vertex( ctx, v0 ); 391 _swrast_print_vertex( ctx, v1 ); 392 _swrast_print_vertex( ctx, v2 ); 393 } 394 SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 ); 395} 396 397void 398_swrast_Line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) 399{ 400 if (SWRAST_DEBUG) { 401 fprintf(stderr, "_swrast_Line\n"); 402 _swrast_print_vertex( ctx, v0 ); 403 _swrast_print_vertex( ctx, v1 ); 404 } 405 SWRAST_CONTEXT(ctx)->Line( ctx, v0, v1 ); 406} 407 408void 409_swrast_Point( GLcontext *ctx, const SWvertex *v0 ) 410{ 411 if (SWRAST_DEBUG) { 412 fprintf(stderr, "_swrast_Point\n"); 413 _swrast_print_vertex( ctx, v0 ); 414 } 415 SWRAST_CONTEXT(ctx)->Point( ctx, v0 ); 416} 417 418void 419_swrast_InvalidateState( GLcontext *ctx, GLuint new_state ) 420{ 421 if (SWRAST_DEBUG) { 422 fprintf(stderr, "_swrast_InvalidateState\n"); 423 } 424 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, new_state ); 425} 426 427void 428_swrast_ResetLineStipple( GLcontext *ctx ) 429{ 430 if (SWRAST_DEBUG) { 431 fprintf(stderr, "_swrast_ResetLineStipple\n"); 432 } 433 SWRAST_CONTEXT(ctx)->StippleCounter = 0; 434} 435 436void 437_swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value ) 438{ 439 if (SWRAST_DEBUG) { 440 fprintf(stderr, "_swrast_allow_vertex_fog %d\n", value); 441 } 442 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); 443 SWRAST_CONTEXT(ctx)->AllowVertexFog = value; 444} 445 446void 447_swrast_allow_pixel_fog( GLcontext *ctx, GLboolean value ) 448{ 449 if (SWRAST_DEBUG) { 450 fprintf(stderr, "_swrast_allow_pixel_fog %d\n", value); 451 } 452 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); 453 SWRAST_CONTEXT(ctx)->AllowPixelFog = value; 454} 455 456 457GLboolean 458_swrast_CreateContext( GLcontext *ctx ) 459{ 460 GLuint i; 461 SWcontext *swrast = (SWcontext *)CALLOC(sizeof(SWcontext)); 462 463 if (SWRAST_DEBUG) { 464 fprintf(stderr, "_swrast_CreateContext\n"); 465 } 466 467 if (!swrast) 468 return GL_FALSE; 469 470 swrast->PB = _mesa_alloc_pb(); 471 if (!swrast->PB) { 472 FREE(swrast); 473 return GL_FALSE; 474 } 475 476 swrast->NewState = ~0; 477 478 swrast->choose_point = _swrast_choose_point; 479 swrast->choose_line = _swrast_choose_line; 480 swrast->choose_triangle = _swrast_choose_triangle; 481 482 swrast->invalidate_point = _SWRAST_NEW_POINT; 483 swrast->invalidate_line = _SWRAST_NEW_LINE; 484 swrast->invalidate_triangle = _SWRAST_NEW_TRIANGLE; 485 486 swrast->Point = _swrast_validate_point; 487 swrast->Line = _swrast_validate_line; 488 swrast->Triangle = _swrast_validate_triangle; 489 swrast->InvalidateState = _swrast_sleep; 490 swrast->BlendFunc = _swrast_validate_blend_func; 491 492 swrast->AllowVertexFog = GL_TRUE; 493 swrast->AllowPixelFog = GL_TRUE; 494 495 /* Optimized Accum buffer */ 496 swrast->_IntegerAccumMode = GL_TRUE; 497 swrast->_IntegerAccumScaler = 0.0; 498 499 500 for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) 501 swrast->TextureSample[i] = _swrast_validate_texture_sample; 502 503 ctx->swrast_context = swrast; 504 return GL_TRUE; 505} 506 507void 508_swrast_DestroyContext( GLcontext *ctx ) 509{ 510 SWcontext *swrast = SWRAST_CONTEXT(ctx); 511 512 if (SWRAST_DEBUG) { 513 fprintf(stderr, "_swrast_DestroyContext\n"); 514 } 515 516 FREE( swrast->PB ); 517 FREE( swrast ); 518 519 ctx->swrast_context = 0; 520} 521 522 523struct swrast_device_driver * 524_swrast_GetDeviceDriverReference( GLcontext *ctx ) 525{ 526 SWcontext *swrast = SWRAST_CONTEXT(ctx); 527 return &swrast->Driver; 528} 529 530#define SWRAST_DEBUG_VERTICES 0 531 532void 533_swrast_print_vertex( GLcontext *ctx, const SWvertex *v ) 534{ 535 GLuint i; 536 537 if (SWRAST_DEBUG_VERTICES) { 538 fprintf(stderr, "win %f %f %f %f\n", 539 v->win[0], v->win[1], v->win[2], v->win[3]); 540 541 for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) 542 if (ctx->Texture.Unit[i]._ReallyEnabled) 543 fprintf(stderr, "texcoord[%d] %f %f %f %f\n", i, 544 v->texcoord[i][0], v->texcoord[i][1], 545 v->texcoord[i][2], v->texcoord[i][3]); 546 547#if CHAN_TYPE == GL_FLOAT 548 fprintf(stderr, "color %f %f %f %f\n", 549 v->color[0], v->color[1], v->color[2], v->color[3]); 550 fprintf(stderr, "spec %f %f %f %f\n", 551 v->specular[0], v->specular[1], v->specular[2], v->specular[3]); 552#else 553 fprintf(stderr, "color %d %d %d %d\n", 554 v->color[0], v->color[1], v->color[2], v->color[3]); 555 fprintf(stderr, "spec %d %d %d %d\n", 556 v->specular[0], v->specular[1], v->specular[2], v->specular[3]); 557#endif 558 fprintf(stderr, "fog %f\n", v->fog); 559 fprintf(stderr, "index %d\n", v->index); 560 fprintf(stderr, "pointsize %f\n", v->pointSize); 561 fprintf(stderr, "\n"); 562 } 563} 564