s_context.c revision 89dae684aa1d74b06a4f70cb76b33671d0cef9e6
1/* $Id: s_context.c,v 1.21 2001/05/17 09:32:17 keithw Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 3.5 6 * 7 * Copyright (C) 1999-2001 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, 267 const GLfloat s[], const GLfloat t[], 268 const GLfloat u[], const GLfloat lambda[], 269 GLchan rgba[][4] ) 270{ 271 SWcontext *swrast = SWRAST_CONTEXT(ctx); 272 273 _swrast_validate_derived( ctx ); 274 _swrast_choose_texture_sample_func( ctx, texUnit, tObj ); 275 276 swrast->TextureSample[texUnit]( ctx, texUnit, tObj, n, s, t, u, 277 lambda, rgba ); 278} 279 280 281static void 282_swrast_sleep( GLcontext *ctx, GLuint new_state ) 283{ 284} 285 286 287static void 288_swrast_invalidate_state( GLcontext *ctx, GLuint new_state ) 289{ 290 SWcontext *swrast = SWRAST_CONTEXT(ctx); 291 GLuint i; 292 293 swrast->NewState |= new_state; 294 295 /* After 10 statechanges without any swrast functions being called, 296 * put the module to sleep. 297 */ 298 if (++swrast->StateChanges > 10) { 299 swrast->InvalidateState = _swrast_sleep; 300 swrast->NewState = ~0; 301 new_state = ~0; 302 } 303 304 if (new_state & swrast->invalidate_triangle) 305 swrast->Triangle = _swrast_validate_triangle; 306 307 if (new_state & swrast->invalidate_line) 308 swrast->Line = _swrast_validate_line; 309 310 if (new_state & swrast->invalidate_point) 311 swrast->Point = _swrast_validate_point; 312 313 if (new_state & _SWRAST_NEW_BLEND_FUNC) 314 swrast->BlendFunc = _swrast_validate_blend_func; 315 316 if (new_state & _SWRAST_NEW_TEXTURE_SAMPLE_FUNC) 317 for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) 318 swrast->TextureSample[i] = _swrast_validate_texture_sample; 319 320 321 if (ctx->Visual.rgbMode) { 322 ASSERT(swrast->Driver.WriteRGBASpan); 323 ASSERT(swrast->Driver.WriteRGBSpan); 324 ASSERT(swrast->Driver.WriteMonoRGBASpan); 325 ASSERT(swrast->Driver.WriteRGBAPixels); 326 ASSERT(swrast->Driver.WriteMonoRGBAPixels); 327 ASSERT(swrast->Driver.ReadRGBASpan); 328 ASSERT(swrast->Driver.ReadRGBAPixels); 329 } 330 else { 331 ASSERT(swrast->Driver.WriteCI32Span); 332 ASSERT(swrast->Driver.WriteCI8Span); 333 ASSERT(swrast->Driver.WriteMonoCISpan); 334 ASSERT(swrast->Driver.WriteCI32Pixels); 335 ASSERT(swrast->Driver.WriteMonoCIPixels); 336 ASSERT(swrast->Driver.ReadCI32Span); 337 ASSERT(swrast->Driver.ReadCI32Pixels); 338 } 339 340} 341 342 343 344void 345_swrast_validate_derived( GLcontext *ctx ) 346{ 347 SWcontext *swrast = SWRAST_CONTEXT(ctx); 348 349 if (swrast->NewState) 350 { 351 if (swrast->NewState & _SWRAST_NEW_RASTERMASK) 352 _swrast_update_rasterflags( ctx ); 353 354 if (swrast->NewState & _NEW_POLYGON) 355 _swrast_update_polygon( ctx ); 356 357 if (swrast->NewState & _NEW_HINT) 358 _swrast_update_hint( ctx ); 359 360 swrast->NewState = 0; 361 swrast->StateChanges = 0; 362 swrast->InvalidateState = _swrast_invalidate_state; 363 } 364} 365 366#define SWRAST_DEBUG 0 367 368/* Public entrypoints: See also s_accum.c, s_bitmap.c, etc. 369 */ 370void 371_swrast_Quad( GLcontext *ctx, 372 const SWvertex *v0, const SWvertex *v1, 373 const SWvertex *v2, const SWvertex *v3 ) 374{ 375 if (SWRAST_DEBUG) { 376 fprintf(stderr, "_swrast_Quad\n"); 377 _swrast_print_vertex( ctx, v0 ); 378 _swrast_print_vertex( ctx, v1 ); 379 _swrast_print_vertex( ctx, v2 ); 380 _swrast_print_vertex( ctx, v3 ); 381 } 382 SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v3 ); 383 SWRAST_CONTEXT(ctx)->Triangle( ctx, v1, v2, v3 ); 384} 385 386void 387_swrast_Triangle( GLcontext *ctx, const SWvertex *v0, 388 const SWvertex *v1, const SWvertex *v2 ) 389{ 390 if (SWRAST_DEBUG) { 391 fprintf(stderr, "_swrast_Triangle\n"); 392 _swrast_print_vertex( ctx, v0 ); 393 _swrast_print_vertex( ctx, v1 ); 394 _swrast_print_vertex( ctx, v2 ); 395 } 396 SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 ); 397} 398 399void 400_swrast_Line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) 401{ 402 if (SWRAST_DEBUG) { 403 fprintf(stderr, "_swrast_Line\n"); 404 _swrast_print_vertex( ctx, v0 ); 405 _swrast_print_vertex( ctx, v1 ); 406 } 407 SWRAST_CONTEXT(ctx)->Line( ctx, v0, v1 ); 408} 409 410void 411_swrast_Point( GLcontext *ctx, const SWvertex *v0 ) 412{ 413 if (SWRAST_DEBUG) { 414 fprintf(stderr, "_swrast_Point\n"); 415 _swrast_print_vertex( ctx, v0 ); 416 } 417 SWRAST_CONTEXT(ctx)->Point( ctx, v0 ); 418} 419 420void 421_swrast_InvalidateState( GLcontext *ctx, GLuint new_state ) 422{ 423 if (SWRAST_DEBUG) { 424 fprintf(stderr, "_swrast_InvalidateState\n"); 425 } 426 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, new_state ); 427} 428 429void 430_swrast_ResetLineStipple( GLcontext *ctx ) 431{ 432 if (SWRAST_DEBUG) { 433 fprintf(stderr, "_swrast_ResetLineStipple\n"); 434 } 435 SWRAST_CONTEXT(ctx)->StippleCounter = 0; 436} 437 438void 439_swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value ) 440{ 441 if (SWRAST_DEBUG) { 442 fprintf(stderr, "_swrast_allow_vertex_fog %d\n", value); 443 } 444 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); 445 SWRAST_CONTEXT(ctx)->AllowVertexFog = value; 446} 447 448void 449_swrast_allow_pixel_fog( GLcontext *ctx, GLboolean value ) 450{ 451 if (SWRAST_DEBUG) { 452 fprintf(stderr, "_swrast_allow_pixel_fog %d\n", value); 453 } 454 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); 455 SWRAST_CONTEXT(ctx)->AllowPixelFog = value; 456} 457 458 459GLboolean 460_swrast_CreateContext( GLcontext *ctx ) 461{ 462 GLuint i; 463 SWcontext *swrast = (SWcontext *)CALLOC(sizeof(SWcontext)); 464 465 if (SWRAST_DEBUG) { 466 fprintf(stderr, "_swrast_CreateContext\n"); 467 } 468 469 if (!swrast) 470 return GL_FALSE; 471 472 swrast->PB = _mesa_alloc_pb(); 473 if (!swrast->PB) { 474 FREE(swrast); 475 return GL_FALSE; 476 } 477 478 swrast->NewState = ~0; 479 480 swrast->choose_point = _swrast_choose_point; 481 swrast->choose_line = _swrast_choose_line; 482 swrast->choose_triangle = _swrast_choose_triangle; 483 484 swrast->invalidate_point = _SWRAST_NEW_POINT; 485 swrast->invalidate_line = _SWRAST_NEW_LINE; 486 swrast->invalidate_triangle = _SWRAST_NEW_TRIANGLE; 487 488 swrast->Point = _swrast_validate_point; 489 swrast->Line = _swrast_validate_line; 490 swrast->Triangle = _swrast_validate_triangle; 491 swrast->InvalidateState = _swrast_sleep; 492 swrast->BlendFunc = _swrast_validate_blend_func; 493 494 swrast->AllowVertexFog = GL_TRUE; 495 swrast->AllowPixelFog = GL_TRUE; 496 497 /* Optimized Accum buffer */ 498 swrast->_IntegerAccumMode = GL_TRUE; 499 swrast->_IntegerAccumScaler = 0.0; 500 501 502 for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) 503 swrast->TextureSample[i] = _swrast_validate_texture_sample; 504 505 ctx->swrast_context = swrast; 506 return GL_TRUE; 507} 508 509void 510_swrast_DestroyContext( GLcontext *ctx ) 511{ 512 SWcontext *swrast = SWRAST_CONTEXT(ctx); 513 514 if (SWRAST_DEBUG) { 515 fprintf(stderr, "_swrast_DestroyContext\n"); 516 } 517 518 FREE( swrast->PB ); 519 FREE( swrast ); 520 521 ctx->swrast_context = 0; 522} 523 524 525struct swrast_device_driver * 526_swrast_GetDeviceDriverReference( GLcontext *ctx ) 527{ 528 SWcontext *swrast = SWRAST_CONTEXT(ctx); 529 return &swrast->Driver; 530} 531 532#define SWRAST_DEBUG_VERTICES 0 533 534void 535_swrast_print_vertex( GLcontext *ctx, const SWvertex *v ) 536{ 537 GLuint i; 538 539 if (SWRAST_DEBUG_VERTICES) { 540 fprintf(stderr, "win %f %f %f %f\n", 541 v->win[0], v->win[1], v->win[2], v->win[3]); 542 543 for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) 544 fprintf(stderr, "texcoord[%d] %f %f %f %f\n", i, 545 v->texcoord[i][0], v->texcoord[i][1], 546 v->texcoord[i][2], v->texcoord[i][3]); 547 548 fprintf(stderr, "color %d %d %d %d\n", 549 v->color[0], v->color[1], v->color[2], v->color[3]); 550 fprintf(stderr, "spec %d %d %d %d\n", 551 v->specular[0], v->specular[1], v->specular[2], v->specular[3]); 552 fprintf(stderr, "fog %f\n", v->fog); 553 fprintf(stderr, "index %d\n", v->index); 554 fprintf(stderr, "pointsize %f\n", v->pointSize); 555 fprintf(stderr, "\n"); 556 } 557} 558