s_context.c revision b6bcae5698df88f7730d40004ce7ce0462e97a20
1/* $Id: s_context.c,v 1.11 2001/01/23 23:39:37 brianp Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 3.5 6 * 7 * Copyright (C) 1999 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_quads.h" 39#include "s_blend.h" 40#include "s_context.h" 41#include "s_texture.h" 42 43 44 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 |= SCISSOR_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.ColorLogicOpEnabled) RasterMask |= LOGIC_OP_BIT; 66 if (ctx->Texture._ReallyEnabled) 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 > ctx->DrawBuffer->Width 80 || ctx->Viewport.Y < 0 81 || ctx->Viewport.Y + ctx->Viewport.Height > ctx->DrawBuffer->Height) { 82 RasterMask |= WINCLIP_BIT; 83 } 84 85 if (ctx->Depth.OcclusionTest) 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.MultiDrawBuffer) { 94 RasterMask |= MULTI_DRAW_BIT; 95 } 96 else if (ctx->Color.DrawBuffer==GL_NONE) { 97 RasterMask |= MULTI_DRAW_BIT; 98 } 99 else if (ctx->Visual.rgbMode && *((GLuint *) ctx->Color.ColorMask) == 0) { 100 RasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */ 101 } 102 else if (!ctx->Visual.rgbMode && ctx->Color.IndexMask==0) { 103 RasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */ 104 } 105 106 if ( ctx->Viewport.X<0 107 || ctx->Viewport.X + ctx->Viewport.Width > ctx->DrawBuffer->Width 108 || ctx->Viewport.Y<0 109 || ctx->Viewport.Y + ctx->Viewport.Height > ctx->DrawBuffer->Height) { 110 RasterMask |= WINCLIP_BIT; 111 } 112 113 SWRAST_CONTEXT(ctx)->_RasterMask = RasterMask; 114} 115 116 117static void 118_swrast_update_polygon( GLcontext *ctx ) 119{ 120 GLfloat backface_sign = 1; 121 122 if (ctx->Polygon.CullFlag) { 123 backface_sign = 1; 124 switch(ctx->Polygon.CullFaceMode) { 125 case GL_BACK: 126 if(ctx->Polygon.FrontFace==GL_CCW) 127 backface_sign = -1; 128 break; 129 case GL_FRONT: 130 if(ctx->Polygon.FrontFace!=GL_CCW) 131 backface_sign = -1; 132 break; 133 default: 134 case GL_FRONT_AND_BACK: 135 backface_sign = 0; 136 break; 137 } 138 } 139 else { 140 backface_sign = 0; 141 } 142 143 SWRAST_CONTEXT(ctx)->_backface_sign = backface_sign; 144} 145 146 147static void 148_swrast_update_hint( GLcontext *ctx ) 149{ 150 SWcontext *swrast = SWRAST_CONTEXT(ctx); 151 swrast->_PreferPixelFog = (!swrast->AllowVertexFog || 152 (ctx->Hint.Fog == GL_NICEST && 153 swrast->AllowPixelFog)); 154} 155 156#define _SWRAST_NEW_TRIANGLE (_NEW_RENDERMODE| \ 157 _NEW_POLYGON| \ 158 _NEW_DEPTH| \ 159 _NEW_STENCIL| \ 160 _NEW_COLOR| \ 161 _NEW_TEXTURE| \ 162 _NEW_HINT| \ 163 _SWRAST_NEW_RASTERMASK| \ 164 _NEW_LIGHT| \ 165 _NEW_FOG) 166 167#define _SWRAST_NEW_LINE (_NEW_RENDERMODE| \ 168 _NEW_LINE| \ 169 _NEW_TEXTURE| \ 170 _NEW_LIGHT| \ 171 _NEW_FOG| \ 172 _NEW_DEPTH) 173 174#define _SWRAST_NEW_POINT (_NEW_RENDERMODE | \ 175 _NEW_POINT | \ 176 _NEW_TEXTURE | \ 177 _NEW_LIGHT | \ 178 _NEW_FOG) 179 180#define _SWRAST_NEW_QUAD 0 181 182#define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE 183 184#define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR 185 186 187 188/* Stub for swrast->Triangle to select a true triangle function 189 * after a state change. 190 */ 191static void 192_swrast_validate_quad( GLcontext *ctx, 193 const SWvertex *v0, const SWvertex *v1, 194 const SWvertex *v2, const SWvertex *v3 ) 195{ 196 SWcontext *swrast = SWRAST_CONTEXT(ctx); 197 198 _swrast_validate_derived( ctx ); 199 swrast->choose_quad( ctx ); 200 201 swrast->Quad( ctx, v0, v1, v2, v3 ); 202} 203 204static void 205_swrast_validate_triangle( GLcontext *ctx, 206 const SWvertex *v0, 207 const SWvertex *v1, 208 const SWvertex *v2 ) 209{ 210 SWcontext *swrast = SWRAST_CONTEXT(ctx); 211 212 _swrast_validate_derived( ctx ); 213 swrast->choose_triangle( ctx ); 214 215 swrast->Triangle( ctx, v0, v1, v2 ); 216} 217 218static void 219_swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) 220{ 221 SWcontext *swrast = SWRAST_CONTEXT(ctx); 222 223 _swrast_validate_derived( ctx ); 224 swrast->choose_line( ctx ); 225 226 swrast->Line( ctx, v0, v1 ); 227} 228 229static void 230_swrast_validate_point( GLcontext *ctx, const SWvertex *v0 ) 231{ 232 SWcontext *swrast = SWRAST_CONTEXT(ctx); 233 234 _swrast_validate_derived( ctx ); 235 swrast->choose_point( ctx ); 236 237 swrast->Point( ctx, v0 ); 238} 239 240static void 241_swrast_validate_blend_func( GLcontext *ctx, GLuint n, 242 const GLubyte mask[], 243 GLchan src[][4], 244 CONST GLchan dst[][4] ) 245{ 246 SWcontext *swrast = SWRAST_CONTEXT(ctx); 247 248 _swrast_validate_derived( ctx ); 249 _swrast_choose_blend_func( ctx ); 250 251 swrast->BlendFunc( ctx, n, mask, src, dst ); 252} 253 254 255static void 256_swrast_validate_texture_sample( GLcontext *ctx, GLuint texUnit, 257 const struct gl_texture_object *tObj, 258 GLuint n, 259 const GLfloat s[], const GLfloat t[], 260 const GLfloat u[], const GLfloat lambda[], 261 GLchan rgba[][4] ) 262{ 263 SWcontext *swrast = SWRAST_CONTEXT(ctx); 264 265 _swrast_validate_derived( ctx ); 266 _swrast_choose_texture_sample_func( ctx, texUnit, tObj ); 267 268 swrast->TextureSample[texUnit]( ctx, texUnit, tObj, n, s, t, u, 269 lambda, rgba ); 270} 271 272 273static void 274_swrast_sleep( GLcontext *ctx, GLuint new_state ) 275{ 276} 277 278 279static void 280_swrast_invalidate_state( GLcontext *ctx, GLuint new_state ) 281{ 282 SWcontext *swrast = SWRAST_CONTEXT(ctx); 283 GLuint i; 284 285 swrast->NewState |= new_state; 286 287 /* After 10 statechanges without any swrast functions being called, 288 * put the module to sleep. 289 */ 290 if (++swrast->StateChanges > 10) { 291 swrast->InvalidateState = _swrast_sleep; 292 swrast->NewState = ~0; 293 new_state = ~0; 294 } 295 296 if (new_state & swrast->invalidate_triangle) 297 swrast->Triangle = _swrast_validate_triangle; 298 299 if (new_state & swrast->invalidate_line) 300 swrast->Line = _swrast_validate_line; 301 302 if (new_state & swrast->invalidate_point) 303 swrast->Point = _swrast_validate_point; 304 305 if (new_state & swrast->invalidate_quad) 306 swrast->Quad = _swrast_validate_quad; 307 308 if (new_state & _SWRAST_NEW_BLEND_FUNC) 309 swrast->BlendFunc = _swrast_validate_blend_func; 310 311 if (new_state & _SWRAST_NEW_TEXTURE_SAMPLE_FUNC) 312 for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) 313 swrast->TextureSample[i] = _swrast_validate_texture_sample; 314} 315 316 317 318void 319_swrast_validate_derived( GLcontext *ctx ) 320{ 321 SWcontext *swrast = SWRAST_CONTEXT(ctx); 322 323 if (swrast->NewState) 324 { 325 if (swrast->NewState & _SWRAST_NEW_RASTERMASK) 326 _swrast_update_rasterflags( ctx ); 327 328 if (swrast->NewState & _NEW_TEXTURE) 329 swrast->_MultiTextureEnabled = (ctx->Texture._ReallyEnabled & 330 ~TEXTURE0_ANY); 331 332 if (swrast->NewState & _NEW_POLYGON) 333 _swrast_update_polygon( ctx ); 334 335 if (swrast->NewState & _NEW_HINT) 336 _swrast_update_hint( ctx ); 337 338 swrast->NewState = 0; 339 swrast->StateChanges = 0; 340 swrast->InvalidateState = _swrast_invalidate_state; 341 } 342} 343 344 345 346/* Public entrypoints: See also s_accum.c, s_bitmap.c, etc. 347 */ 348void 349_swrast_Quad( GLcontext *ctx, 350 const SWvertex *v0, const SWvertex *v1, 351 const SWvertex *v2, const SWvertex *v3 ) 352{ 353/* fprintf(stderr, "%s\n", __FUNCTION__); */ 354/* _swrast_print_vertex( ctx, v0 ); */ 355/* _swrast_print_vertex( ctx, v1 ); */ 356/* _swrast_print_vertex( ctx, v2 ); */ 357/* _swrast_print_vertex( ctx, v3 ); */ 358 SWRAST_CONTEXT(ctx)->Quad( ctx, v0, v1, v2, v3 ); 359} 360 361void 362_swrast_Triangle( GLcontext *ctx, const SWvertex *v0, 363 const SWvertex *v1, const SWvertex *v2 ) 364{ 365/* fprintf(stderr, "%s\n", __FUNCTION__); */ 366/* _swrast_print_vertex( ctx, v0 ); */ 367/* _swrast_print_vertex( ctx, v1 ); */ 368/* _swrast_print_vertex( ctx, v2 ); */ 369 SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 ); 370} 371 372void 373_swrast_Line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) 374{ 375/* fprintf(stderr, "%s\n", __FUNCTION__); */ 376/* _swrast_print_vertex( ctx, v0 ); */ 377/* _swrast_print_vertex( ctx, v1 ); */ 378 SWRAST_CONTEXT(ctx)->Line( ctx, v0, v1 ); 379} 380 381void 382_swrast_Point( GLcontext *ctx, const SWvertex *v0 ) 383{ 384/* fprintf(stderr, "%s\n", __FUNCTION__); */ 385/* _swrast_print_vertex( ctx, v0 ); */ 386 SWRAST_CONTEXT(ctx)->Point( ctx, v0 ); 387} 388 389void 390_swrast_InvalidateState( GLcontext *ctx, GLuint new_state ) 391{ 392 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, new_state ); 393} 394 395void 396_swrast_ResetLineStipple( GLcontext *ctx ) 397{ 398 SWRAST_CONTEXT(ctx)->StippleCounter = 0; 399} 400 401void 402_swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value ) 403{ 404 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); 405 SWRAST_CONTEXT(ctx)->AllowVertexFog = value; 406} 407 408void 409_swrast_allow_pixel_fog( GLcontext *ctx, GLboolean value ) 410{ 411 SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); 412 SWRAST_CONTEXT(ctx)->AllowPixelFog = value; 413} 414 415 416GLboolean 417_swrast_CreateContext( GLcontext *ctx ) 418{ 419 GLuint i; 420 SWcontext *swrast = (SWcontext *)CALLOC(sizeof(SWcontext)); 421 if (!swrast) 422 return GL_FALSE; 423 424 swrast->PB = gl_alloc_pb(); 425 if (!swrast->PB) { 426 FREE(swrast); 427 return GL_FALSE; 428 } 429 430 swrast->NewState = ~0; 431 432 swrast->choose_point = _swrast_choose_point; 433 swrast->choose_line = _swrast_choose_line; 434 swrast->choose_triangle = _swrast_choose_triangle; 435 swrast->choose_quad = _swrast_choose_quad; 436 437 swrast->invalidate_point = _SWRAST_NEW_POINT; 438 swrast->invalidate_line = _SWRAST_NEW_LINE; 439 swrast->invalidate_triangle = _SWRAST_NEW_TRIANGLE; 440 swrast->invalidate_quad = _SWRAST_NEW_QUAD; 441 442 swrast->Point = _swrast_validate_point; 443 swrast->Line = _swrast_validate_line; 444 swrast->Triangle = _swrast_validate_triangle; 445 swrast->Quad = _swrast_validate_quad; 446 swrast->InvalidateState = _swrast_sleep; 447 swrast->BlendFunc = _swrast_validate_blend_func; 448 449 swrast->AllowVertexFog = GL_TRUE; 450 swrast->AllowPixelFog = GL_TRUE; 451 452 /* Optimized Accum buffer */ 453 swrast->_IntegerAccumMode = GL_TRUE; 454 swrast->_IntegerAccumScaler = 0.0; 455 456 457 for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) 458 swrast->TextureSample[i] = _swrast_validate_texture_sample; 459 460 ctx->swrast_context = swrast; 461 return GL_TRUE; 462} 463 464void 465_swrast_DestroyContext( GLcontext *ctx ) 466{ 467 SWcontext *swrast = SWRAST_CONTEXT(ctx); 468 469 FREE( swrast->PB ); 470 FREE( swrast ); 471 472 ctx->swrast_context = 0; 473} 474 475 476void 477_swrast_print_vertex( GLcontext *ctx, const SWvertex *v ) 478{ 479 GLuint i; 480 481 fprintf(stderr, "win %f %f %f %f\n", 482 v->win[0], v->win[1], v->win[2], v->win[3]); 483 484 for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) 485 fprintf(stderr, "texcoord[%d] %f %f %f %f\n", i, 486 v->texcoord[i][0], v->texcoord[i][1], 487 v->texcoord[i][2], v->texcoord[i][3]); 488 489 fprintf(stderr, "color %d %d %d %d\n", 490 v->color[0], v->color[1], v->color[2], v->color[3]); 491 fprintf(stderr, "spec %d %d %d %d\n", 492 v->specular[0], v->specular[1], v->specular[2], v->specular[3]); 493 fprintf(stderr, "fog %f\n", v->fog); 494 fprintf(stderr, "index %d\n", v->index); 495 fprintf(stderr, "pointsize %f\n", v->pointSize); 496 fprintf(stderr, "\n"); 497} 498