state.c revision c1f859d4
17117f1b4Smrg/* 27117f1b4Smrg * Mesa 3-D graphics library 3c1f859d4Smrg * Version: 7.1 47117f1b4Smrg * 5c1f859d4Smrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 67117f1b4Smrg * 77117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a 87117f1b4Smrg * copy of this software and associated documentation files (the "Software"), 97117f1b4Smrg * to deal in the Software without restriction, including without limitation 107117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 117117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the 127117f1b4Smrg * Software is furnished to do so, subject to the following conditions: 137117f1b4Smrg * 147117f1b4Smrg * The above copyright notice and this permission notice shall be included 157117f1b4Smrg * in all copies or substantial portions of the Software. 167117f1b4Smrg * 177117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 187117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 197117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 207117f1b4Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 217117f1b4Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 227117f1b4Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 237117f1b4Smrg */ 247117f1b4Smrg 257117f1b4Smrg 267117f1b4Smrg/** 277117f1b4Smrg * \file state.c 287117f1b4Smrg * State management. 297117f1b4Smrg * 30c1f859d4Smrg * This file manages recalculation of derived values in GLcontext. 317117f1b4Smrg */ 327117f1b4Smrg 33c1f859d4Smrg 347117f1b4Smrg#include "glheader.h" 35c1f859d4Smrg#include "mtypes.h" 367117f1b4Smrg#include "context.h" 37c1f859d4Smrg#include "debug.h" 38c1f859d4Smrg#include "macros.h" 39c1f859d4Smrg#include "ffvertex_prog.h" 407117f1b4Smrg#include "framebuffer.h" 417117f1b4Smrg#include "light.h" 427117f1b4Smrg#include "matrix.h" 43c1f859d4Smrg#if FEATURE_pixel_transfer 447117f1b4Smrg#include "pixel.h" 457117f1b4Smrg#endif 46c1f859d4Smrg#include "shader/program.h" 477117f1b4Smrg#include "state.h" 487117f1b4Smrg#include "stencil.h" 49c1f859d4Smrg#include "texenvprogram.h" 507117f1b4Smrg#include "texobj.h" 517117f1b4Smrg#include "texstate.h" 527117f1b4Smrg 537117f1b4Smrg 547117f1b4Smrgstatic void 55c1f859d4Smrgupdate_separate_specular(GLcontext *ctx) 567117f1b4Smrg{ 577117f1b4Smrg if (NEED_SECONDARY_COLOR(ctx)) 587117f1b4Smrg ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR; 597117f1b4Smrg else 607117f1b4Smrg ctx->_TriangleCaps &= ~DD_SEPARATE_SPECULAR; 617117f1b4Smrg} 627117f1b4Smrg 637117f1b4Smrg 647117f1b4Smrg/** 657117f1b4Smrg * Update state dependent on vertex arrays. 667117f1b4Smrg */ 677117f1b4Smrgstatic void 687117f1b4Smrgupdate_arrays( GLcontext *ctx ) 697117f1b4Smrg{ 707117f1b4Smrg GLuint i, min; 717117f1b4Smrg 727117f1b4Smrg /* find min of _MaxElement values for all enabled arrays */ 737117f1b4Smrg 747117f1b4Smrg /* 0 */ 757117f1b4Smrg if (ctx->VertexProgram._Current 767117f1b4Smrg && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) { 777117f1b4Smrg min = ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS]._MaxElement; 787117f1b4Smrg } 797117f1b4Smrg else if (ctx->Array.ArrayObj->Vertex.Enabled) { 807117f1b4Smrg min = ctx->Array.ArrayObj->Vertex._MaxElement; 817117f1b4Smrg } 827117f1b4Smrg else { 837117f1b4Smrg /* can't draw anything without vertex positions! */ 847117f1b4Smrg min = 0; 857117f1b4Smrg } 867117f1b4Smrg 877117f1b4Smrg /* 1 */ 887117f1b4Smrg if (ctx->VertexProgram._Enabled 897117f1b4Smrg && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT].Enabled) { 907117f1b4Smrg min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT]._MaxElement); 917117f1b4Smrg } 927117f1b4Smrg /* no conventional vertex weight array */ 937117f1b4Smrg 947117f1b4Smrg /* 2 */ 957117f1b4Smrg if (ctx->VertexProgram._Enabled 967117f1b4Smrg && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) { 977117f1b4Smrg min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]._MaxElement); 987117f1b4Smrg } 997117f1b4Smrg else if (ctx->Array.ArrayObj->Normal.Enabled) { 1007117f1b4Smrg min = MIN2(min, ctx->Array.ArrayObj->Normal._MaxElement); 1017117f1b4Smrg } 1027117f1b4Smrg 1037117f1b4Smrg /* 3 */ 1047117f1b4Smrg if (ctx->VertexProgram._Enabled 1057117f1b4Smrg && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) { 1067117f1b4Smrg min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]._MaxElement); 1077117f1b4Smrg } 1087117f1b4Smrg else if (ctx->Array.ArrayObj->Color.Enabled) { 1097117f1b4Smrg min = MIN2(min, ctx->Array.ArrayObj->Color._MaxElement); 1107117f1b4Smrg } 1117117f1b4Smrg 1127117f1b4Smrg /* 4 */ 1137117f1b4Smrg if (ctx->VertexProgram._Enabled 1147117f1b4Smrg && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) { 1157117f1b4Smrg min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR1]._MaxElement); 1167117f1b4Smrg } 1177117f1b4Smrg else if (ctx->Array.ArrayObj->SecondaryColor.Enabled) { 1187117f1b4Smrg min = MIN2(min, ctx->Array.ArrayObj->SecondaryColor._MaxElement); 1197117f1b4Smrg } 1207117f1b4Smrg 1217117f1b4Smrg /* 5 */ 1227117f1b4Smrg if (ctx->VertexProgram._Enabled 1237117f1b4Smrg && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled) { 1247117f1b4Smrg min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_FOG]._MaxElement); 1257117f1b4Smrg } 1267117f1b4Smrg else if (ctx->Array.ArrayObj->FogCoord.Enabled) { 1277117f1b4Smrg min = MIN2(min, ctx->Array.ArrayObj->FogCoord._MaxElement); 1287117f1b4Smrg } 1297117f1b4Smrg 1307117f1b4Smrg /* 6 */ 1317117f1b4Smrg if (ctx->VertexProgram._Enabled 1327117f1b4Smrg && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) { 1337117f1b4Smrg min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX]._MaxElement); 1347117f1b4Smrg } 1357117f1b4Smrg else if (ctx->Array.ArrayObj->Index.Enabled) { 1367117f1b4Smrg min = MIN2(min, ctx->Array.ArrayObj->Index._MaxElement); 1377117f1b4Smrg } 1387117f1b4Smrg 1397117f1b4Smrg 1407117f1b4Smrg /* 7 */ 1417117f1b4Smrg if (ctx->VertexProgram._Enabled 1427117f1b4Smrg && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) { 1437117f1b4Smrg min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]._MaxElement); 1447117f1b4Smrg } 1457117f1b4Smrg 1467117f1b4Smrg /* 8..15 */ 1477117f1b4Smrg for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++) { 1487117f1b4Smrg if (ctx->VertexProgram._Enabled 1497117f1b4Smrg && ctx->Array.ArrayObj->VertexAttrib[i].Enabled) { 1507117f1b4Smrg min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[i]._MaxElement); 1517117f1b4Smrg } 1527117f1b4Smrg else if (i - VERT_ATTRIB_TEX0 < ctx->Const.MaxTextureCoordUnits 1537117f1b4Smrg && ctx->Array.ArrayObj->TexCoord[i - VERT_ATTRIB_TEX0].Enabled) { 1547117f1b4Smrg min = MIN2(min, ctx->Array.ArrayObj->TexCoord[i - VERT_ATTRIB_TEX0]._MaxElement); 1557117f1b4Smrg } 1567117f1b4Smrg } 1577117f1b4Smrg 1587117f1b4Smrg /* 16..31 */ 1597117f1b4Smrg if (ctx->VertexProgram._Current) { 1607117f1b4Smrg for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) { 1617117f1b4Smrg if (ctx->Array.ArrayObj->VertexAttrib[i].Enabled) { 1627117f1b4Smrg min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[i]._MaxElement); 1637117f1b4Smrg } 1647117f1b4Smrg } 1657117f1b4Smrg } 1667117f1b4Smrg 1677117f1b4Smrg if (ctx->Array.ArrayObj->EdgeFlag.Enabled) { 1687117f1b4Smrg min = MIN2(min, ctx->Array.ArrayObj->EdgeFlag._MaxElement); 1697117f1b4Smrg } 1707117f1b4Smrg 1717117f1b4Smrg /* _MaxElement is one past the last legal array element */ 1727117f1b4Smrg ctx->Array._MaxElement = min; 1737117f1b4Smrg} 1747117f1b4Smrg 1757117f1b4Smrg 1767117f1b4Smrg/** 177c1f859d4Smrg * Update the following fields: 178c1f859d4Smrg * ctx->VertexProgram._Enabled 179c1f859d4Smrg * ctx->FragmentProgram._Enabled 180c1f859d4Smrg * ctx->ATIFragmentShader._Enabled 181c1f859d4Smrg * This needs to be done before texture state validation. 1827117f1b4Smrg */ 1837117f1b4Smrgstatic void 184c1f859d4Smrgupdate_program_enables(GLcontext *ctx) 1857117f1b4Smrg{ 1867117f1b4Smrg /* These _Enabled flags indicate if the program is enabled AND valid. */ 1877117f1b4Smrg ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled 1887117f1b4Smrg && ctx->VertexProgram.Current->Base.Instructions; 1897117f1b4Smrg ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled 1907117f1b4Smrg && ctx->FragmentProgram.Current->Base.Instructions; 1917117f1b4Smrg ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled 1927117f1b4Smrg && ctx->ATIFragmentShader.Current->Instructions[0]; 193c1f859d4Smrg} 194c1f859d4Smrg 195c1f859d4Smrg 196c1f859d4Smrg/** 197c1f859d4Smrg * Update vertex/fragment program state. In particular, update these fields: 198c1f859d4Smrg * ctx->VertexProgram._Current 199c1f859d4Smrg * ctx->VertexProgram._TnlProgram, 200c1f859d4Smrg * These point to the highest priority enabled vertex/fragment program or are 201c1f859d4Smrg * NULL if fixed-function processing is to be done. 202c1f859d4Smrg * 203c1f859d4Smrg * This function needs to be called after texture state validation in case 204c1f859d4Smrg * we're generating a fragment program from fixed-function texture state. 205c1f859d4Smrg * 206c1f859d4Smrg * \return bitfield which will indicate _NEW_PROGRAM state if a new vertex 207c1f859d4Smrg * or fragment program is being used. 208c1f859d4Smrg */ 209c1f859d4Smrgstatic GLbitfield 210c1f859d4Smrgupdate_program(GLcontext *ctx) 211c1f859d4Smrg{ 212c1f859d4Smrg const struct gl_shader_program *shProg = ctx->Shader.CurrentProgram; 213c1f859d4Smrg const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current; 214c1f859d4Smrg const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current; 215c1f859d4Smrg GLbitfield new_state = 0x0; 2167117f1b4Smrg 2177117f1b4Smrg /* 2187117f1b4Smrg * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current 219c1f859d4Smrg * pointers to the programs that should be used for rendering. If either 220c1f859d4Smrg * is NULL, use fixed-function code paths. 2217117f1b4Smrg * 2227117f1b4Smrg * These programs may come from several sources. The priority is as 2237117f1b4Smrg * follows: 2247117f1b4Smrg * 1. OpenGL 2.0/ARB vertex/fragment shaders 2257117f1b4Smrg * 2. ARB/NV vertex/fragment programs 2267117f1b4Smrg * 3. Programs derived from fixed-function state. 227c1f859d4Smrg * 228c1f859d4Smrg * Note: it's possible for a vertex shader to get used with a fragment 229c1f859d4Smrg * program (and vice versa) here, but in practice that shouldn't ever 230c1f859d4Smrg * come up, or matter. 2317117f1b4Smrg */ 2327117f1b4Smrg 233c1f859d4Smrg if (shProg && shProg->LinkStatus && shProg->FragmentProgram) { 234c1f859d4Smrg /* Use shader programs */ 235c1f859d4Smrg _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, 236c1f859d4Smrg shProg->FragmentProgram); 237c1f859d4Smrg } 238c1f859d4Smrg else if (ctx->FragmentProgram._Enabled) { 239c1f859d4Smrg /* use user-defined vertex program */ 240c1f859d4Smrg _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, 241c1f859d4Smrg ctx->FragmentProgram.Current); 242c1f859d4Smrg } 243c1f859d4Smrg else if (ctx->FragmentProgram._MaintainTexEnvProgram) { 244c1f859d4Smrg /* Use fragment program generated from fixed-function state. 245c1f859d4Smrg */ 246c1f859d4Smrg _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, 247c1f859d4Smrg _mesa_get_fixed_func_fragment_program(ctx)); 248c1f859d4Smrg _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, 249c1f859d4Smrg ctx->FragmentProgram._Current); 250c1f859d4Smrg } 251c1f859d4Smrg else { 252c1f859d4Smrg /* no fragment program */ 253c1f859d4Smrg _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); 254c1f859d4Smrg } 2557117f1b4Smrg 256c1f859d4Smrg /* Examine vertex program after fragment program as 257c1f859d4Smrg * _mesa_get_fixed_func_vertex_program() needs to know active 258c1f859d4Smrg * fragprog inputs. 259c1f859d4Smrg */ 260c1f859d4Smrg if (shProg && shProg->LinkStatus && shProg->VertexProgram) { 2617117f1b4Smrg /* Use shader programs */ 262c1f859d4Smrg _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, 263c1f859d4Smrg shProg->VertexProgram); 264c1f859d4Smrg } 265c1f859d4Smrg else if (ctx->VertexProgram._Enabled) { 266c1f859d4Smrg /* use user-defined vertex program */ 267c1f859d4Smrg _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, 268c1f859d4Smrg ctx->VertexProgram.Current); 269c1f859d4Smrg } 270c1f859d4Smrg else if (ctx->VertexProgram._MaintainTnlProgram) { 271c1f859d4Smrg /* Use vertex program generated from fixed-function state. 2727117f1b4Smrg */ 273c1f859d4Smrg _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, 274c1f859d4Smrg _mesa_get_fixed_func_vertex_program(ctx)); 275c1f859d4Smrg _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, 276c1f859d4Smrg ctx->VertexProgram._Current); 2777117f1b4Smrg } 2787117f1b4Smrg else { 279c1f859d4Smrg /* no vertex program */ 280c1f859d4Smrg _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); 281c1f859d4Smrg } 2827117f1b4Smrg 283c1f859d4Smrg /* Let the driver know what's happening: 284c1f859d4Smrg */ 285c1f859d4Smrg if (ctx->FragmentProgram._Current != prevFP) { 286c1f859d4Smrg new_state |= _NEW_PROGRAM; 287c1f859d4Smrg if (ctx->Driver.BindProgram) { 288c1f859d4Smrg ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 289c1f859d4Smrg (struct gl_program *) ctx->FragmentProgram._Current); 2907117f1b4Smrg } 291c1f859d4Smrg } 292c1f859d4Smrg 293c1f859d4Smrg if (ctx->VertexProgram._Current != prevVP) { 294c1f859d4Smrg new_state |= _NEW_PROGRAM; 295c1f859d4Smrg if (ctx->Driver.BindProgram) { 296c1f859d4Smrg ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, 297c1f859d4Smrg (struct gl_program *) ctx->VertexProgram._Current); 2987117f1b4Smrg } 2997117f1b4Smrg } 3007117f1b4Smrg 301c1f859d4Smrg return new_state; 3027117f1b4Smrg} 3037117f1b4Smrg 3047117f1b4Smrg 3057117f1b4Smrgstatic void 3067117f1b4Smrgupdate_viewport_matrix(GLcontext *ctx) 3077117f1b4Smrg{ 3087117f1b4Smrg const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; 3097117f1b4Smrg 3107117f1b4Smrg ASSERT(depthMax > 0); 3117117f1b4Smrg 3127117f1b4Smrg /* Compute scale and bias values. This is really driver-specific 3137117f1b4Smrg * and should be maintained elsewhere if at all. 3147117f1b4Smrg * NOTE: RasterPos uses this. 3157117f1b4Smrg */ 3167117f1b4Smrg _math_matrix_viewport(&ctx->Viewport._WindowMap, 3177117f1b4Smrg ctx->Viewport.X, ctx->Viewport.Y, 3187117f1b4Smrg ctx->Viewport.Width, ctx->Viewport.Height, 3197117f1b4Smrg ctx->Viewport.Near, ctx->Viewport.Far, 3207117f1b4Smrg depthMax); 3217117f1b4Smrg} 3227117f1b4Smrg 3237117f1b4Smrg 324c1f859d4Smrg/** 325c1f859d4Smrg * Update derived multisample state. 326c1f859d4Smrg */ 327c1f859d4Smrgstatic void 328c1f859d4Smrgupdate_multisample(GLcontext *ctx) 329c1f859d4Smrg{ 330c1f859d4Smrg ctx->Multisample._Enabled = GL_FALSE; 331c1f859d4Smrg if (ctx->Multisample.Enabled && 332c1f859d4Smrg ctx->DrawBuffer && 333c1f859d4Smrg ctx->DrawBuffer->Visual.sampleBuffers) 334c1f859d4Smrg ctx->Multisample._Enabled = GL_TRUE; 335c1f859d4Smrg} 336c1f859d4Smrg 337c1f859d4Smrg 3387117f1b4Smrg/** 3397117f1b4Smrg * Update derived color/blend/logicop state. 3407117f1b4Smrg */ 3417117f1b4Smrgstatic void 3427117f1b4Smrgupdate_color(GLcontext *ctx) 3437117f1b4Smrg{ 3447117f1b4Smrg /* This is needed to support 1.1's RGB logic ops AND 3457117f1b4Smrg * 1.0's blending logicops. 3467117f1b4Smrg */ 3477117f1b4Smrg ctx->Color._LogicOpEnabled = RGBA_LOGICOP_ENABLED(ctx); 3487117f1b4Smrg} 3497117f1b4Smrg 3507117f1b4Smrg 3517117f1b4Smrg/* 3527117f1b4Smrg * Check polygon state and set DD_TRI_CULL_FRONT_BACK and/or DD_TRI_OFFSET 3537117f1b4Smrg * in ctx->_TriangleCaps if needed. 3547117f1b4Smrg */ 3557117f1b4Smrgstatic void 356c1f859d4Smrgupdate_polygon(GLcontext *ctx) 3577117f1b4Smrg{ 3587117f1b4Smrg ctx->_TriangleCaps &= ~(DD_TRI_CULL_FRONT_BACK | DD_TRI_OFFSET); 3597117f1b4Smrg 3607117f1b4Smrg if (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) 3617117f1b4Smrg ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK; 3627117f1b4Smrg 363c1f859d4Smrg if ( ctx->Polygon.OffsetPoint 364c1f859d4Smrg || ctx->Polygon.OffsetLine 365c1f859d4Smrg || ctx->Polygon.OffsetFill) 3667117f1b4Smrg ctx->_TriangleCaps |= DD_TRI_OFFSET; 3677117f1b4Smrg} 3687117f1b4Smrg 3697117f1b4Smrg 3707117f1b4Smrg/** 3717117f1b4Smrg * Update the ctx->_TriangleCaps bitfield. 3727117f1b4Smrg * XXX that bitfield should really go away someday! 3737117f1b4Smrg * This function must be called after other update_*() functions since 3747117f1b4Smrg * there are dependencies on some other derived values. 3757117f1b4Smrg */ 3767117f1b4Smrg#if 0 3777117f1b4Smrgstatic void 3787117f1b4Smrgupdate_tricaps(GLcontext *ctx, GLbitfield new_state) 3797117f1b4Smrg{ 3807117f1b4Smrg ctx->_TriangleCaps = 0; 3817117f1b4Smrg 3827117f1b4Smrg /* 3837117f1b4Smrg * Points 3847117f1b4Smrg */ 3857117f1b4Smrg if (1/*new_state & _NEW_POINT*/) { 3867117f1b4Smrg if (ctx->Point.SmoothFlag) 3877117f1b4Smrg ctx->_TriangleCaps |= DD_POINT_SMOOTH; 388c1f859d4Smrg if (ctx->Point.Size != 1.0F) 3897117f1b4Smrg ctx->_TriangleCaps |= DD_POINT_SIZE; 3907117f1b4Smrg if (ctx->Point._Attenuated) 3917117f1b4Smrg ctx->_TriangleCaps |= DD_POINT_ATTEN; 3927117f1b4Smrg } 3937117f1b4Smrg 3947117f1b4Smrg /* 3957117f1b4Smrg * Lines 3967117f1b4Smrg */ 3977117f1b4Smrg if (1/*new_state & _NEW_LINE*/) { 3987117f1b4Smrg if (ctx->Line.SmoothFlag) 3997117f1b4Smrg ctx->_TriangleCaps |= DD_LINE_SMOOTH; 4007117f1b4Smrg if (ctx->Line.StippleFlag) 4017117f1b4Smrg ctx->_TriangleCaps |= DD_LINE_STIPPLE; 402c1f859d4Smrg if (ctx->Line.Width != 1.0) 4037117f1b4Smrg ctx->_TriangleCaps |= DD_LINE_WIDTH; 4047117f1b4Smrg } 4057117f1b4Smrg 4067117f1b4Smrg /* 4077117f1b4Smrg * Polygons 4087117f1b4Smrg */ 4097117f1b4Smrg if (1/*new_state & _NEW_POLYGON*/) { 4107117f1b4Smrg if (ctx->Polygon.SmoothFlag) 4117117f1b4Smrg ctx->_TriangleCaps |= DD_TRI_SMOOTH; 4127117f1b4Smrg if (ctx->Polygon.StippleFlag) 4137117f1b4Smrg ctx->_TriangleCaps |= DD_TRI_STIPPLE; 4147117f1b4Smrg if (ctx->Polygon.FrontMode != GL_FILL 4157117f1b4Smrg || ctx->Polygon.BackMode != GL_FILL) 4167117f1b4Smrg ctx->_TriangleCaps |= DD_TRI_UNFILLED; 4177117f1b4Smrg if (ctx->Polygon.CullFlag 4187117f1b4Smrg && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) 4197117f1b4Smrg ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK; 4207117f1b4Smrg if (ctx->Polygon.OffsetPoint || 4217117f1b4Smrg ctx->Polygon.OffsetLine || 4227117f1b4Smrg ctx->Polygon.OffsetFill) 4237117f1b4Smrg ctx->_TriangleCaps |= DD_TRI_OFFSET; 4247117f1b4Smrg } 4257117f1b4Smrg 4267117f1b4Smrg /* 4277117f1b4Smrg * Lighting and shading 4287117f1b4Smrg */ 4297117f1b4Smrg if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) 4307117f1b4Smrg ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE; 4317117f1b4Smrg if (ctx->Light.ShadeModel == GL_FLAT) 4327117f1b4Smrg ctx->_TriangleCaps |= DD_FLATSHADE; 4337117f1b4Smrg if (NEED_SECONDARY_COLOR(ctx)) 4347117f1b4Smrg ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR; 4357117f1b4Smrg 4367117f1b4Smrg /* 4377117f1b4Smrg * Stencil 4387117f1b4Smrg */ 4397117f1b4Smrg if (ctx->Stencil._TestTwoSide) 4407117f1b4Smrg ctx->_TriangleCaps |= DD_TRI_TWOSTENCIL; 4417117f1b4Smrg} 4427117f1b4Smrg#endif 4437117f1b4Smrg 4447117f1b4Smrg 4457117f1b4Smrg/** 4467117f1b4Smrg * Compute derived GL state. 4477117f1b4Smrg * If __GLcontextRec::NewState is non-zero then this function \b must 4487117f1b4Smrg * be called before rendering anything. 4497117f1b4Smrg * 4507117f1b4Smrg * Calls dd_function_table::UpdateState to perform any internal state 4517117f1b4Smrg * management necessary. 4527117f1b4Smrg * 4537117f1b4Smrg * \sa _mesa_update_modelview_project(), _mesa_update_texture(), 4547117f1b4Smrg * _mesa_update_buffer_bounds(), 4557117f1b4Smrg * _mesa_update_lighting() and _mesa_update_tnl_spaces(). 4567117f1b4Smrg */ 4577117f1b4Smrgvoid 4587117f1b4Smrg_mesa_update_state_locked( GLcontext *ctx ) 4597117f1b4Smrg{ 4607117f1b4Smrg GLbitfield new_state = ctx->NewState; 461c1f859d4Smrg GLbitfield prog_flags = _NEW_PROGRAM; 462c1f859d4Smrg GLbitfield new_prog_state = 0x0; 4637117f1b4Smrg 4647117f1b4Smrg if (MESA_VERBOSE & VERBOSE_STATE) 4657117f1b4Smrg _mesa_print_state("_mesa_update_state", new_state); 4667117f1b4Smrg 467c1f859d4Smrg /* Determine which state flags effect vertex/fragment program state */ 468c1f859d4Smrg if (ctx->FragmentProgram._MaintainTexEnvProgram) { 469c1f859d4Smrg prog_flags |= (_NEW_TEXTURE | _NEW_FOG | _DD_NEW_SEPARATE_SPECULAR); 470c1f859d4Smrg } 471c1f859d4Smrg if (ctx->VertexProgram._MaintainTnlProgram) { 472c1f859d4Smrg prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX | 473c1f859d4Smrg _NEW_TRANSFORM | _NEW_POINT | 474c1f859d4Smrg _NEW_FOG | _NEW_LIGHT | 475c1f859d4Smrg _MESA_NEW_NEED_EYE_COORDS); 476c1f859d4Smrg } 477c1f859d4Smrg 478c1f859d4Smrg /* 479c1f859d4Smrg * Now update derived state info 480c1f859d4Smrg */ 481c1f859d4Smrg 482c1f859d4Smrg if (new_state & prog_flags) 483c1f859d4Smrg update_program_enables( ctx ); 4847117f1b4Smrg 4857117f1b4Smrg if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) 4867117f1b4Smrg _mesa_update_modelview_project( ctx, new_state ); 4877117f1b4Smrg 4887117f1b4Smrg if (new_state & (_NEW_PROGRAM|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX)) 4897117f1b4Smrg _mesa_update_texture( ctx, new_state ); 4907117f1b4Smrg 4917117f1b4Smrg if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) 4927117f1b4Smrg _mesa_update_framebuffer(ctx); 4937117f1b4Smrg 4947117f1b4Smrg if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT)) 4957117f1b4Smrg _mesa_update_draw_buffer_bounds( ctx ); 4967117f1b4Smrg 4977117f1b4Smrg if (new_state & _NEW_POLYGON) 4987117f1b4Smrg update_polygon( ctx ); 4997117f1b4Smrg 5007117f1b4Smrg if (new_state & _NEW_LIGHT) 5017117f1b4Smrg _mesa_update_lighting( ctx ); 5027117f1b4Smrg 5037117f1b4Smrg if (new_state & _NEW_STENCIL) 5047117f1b4Smrg _mesa_update_stencil( ctx ); 5057117f1b4Smrg 506c1f859d4Smrg#if FEATURE_pixel_transfer 5077117f1b4Smrg if (new_state & _IMAGE_NEW_TRANSFER_STATE) 5087117f1b4Smrg _mesa_update_pixel( ctx, new_state ); 509c1f859d4Smrg#endif 5107117f1b4Smrg 5117117f1b4Smrg if (new_state & _DD_NEW_SEPARATE_SPECULAR) 5127117f1b4Smrg update_separate_specular( ctx ); 5137117f1b4Smrg 5147117f1b4Smrg if (new_state & (_NEW_ARRAY | _NEW_PROGRAM)) 5157117f1b4Smrg update_arrays( ctx ); 5167117f1b4Smrg 5177117f1b4Smrg if (new_state & (_NEW_BUFFERS | _NEW_VIEWPORT)) 5187117f1b4Smrg update_viewport_matrix(ctx); 5197117f1b4Smrg 520c1f859d4Smrg if (new_state & _NEW_MULTISAMPLE) 521c1f859d4Smrg update_multisample( ctx ); 522c1f859d4Smrg 5237117f1b4Smrg if (new_state & _NEW_COLOR) 5247117f1b4Smrg update_color( ctx ); 5257117f1b4Smrg 5267117f1b4Smrg#if 0 5277117f1b4Smrg if (new_state & (_NEW_POINT | _NEW_LINE | _NEW_POLYGON | _NEW_LIGHT 5287117f1b4Smrg | _NEW_STENCIL | _DD_NEW_SEPARATE_SPECULAR)) 5297117f1b4Smrg update_tricaps( ctx, new_state ); 5307117f1b4Smrg#endif 5317117f1b4Smrg 5327117f1b4Smrg /* ctx->_NeedEyeCoords is now up to date. 5337117f1b4Smrg * 5347117f1b4Smrg * If the truth value of this variable has changed, update for the 5357117f1b4Smrg * new lighting space and recompute the positions of lights and the 5367117f1b4Smrg * normal transform. 5377117f1b4Smrg * 5387117f1b4Smrg * If the lighting space hasn't changed, may still need to recompute 5397117f1b4Smrg * light positions & normal transforms for other reasons. 5407117f1b4Smrg */ 5417117f1b4Smrg if (new_state & _MESA_NEW_NEED_EYE_COORDS) 5427117f1b4Smrg _mesa_update_tnl_spaces( ctx, new_state ); 5437117f1b4Smrg 544c1f859d4Smrg if (new_state & prog_flags) { 545c1f859d4Smrg /* When we generate programs from fixed-function vertex/fragment state 546c1f859d4Smrg * this call may generate/bind a new program. If so, we need to 547c1f859d4Smrg * propogate the _NEW_PROGRAM flag to the driver. 548c1f859d4Smrg */ 549c1f859d4Smrg new_prog_state |= update_program( ctx ); 550c1f859d4Smrg } 551c1f859d4Smrg 5527117f1b4Smrg /* 5537117f1b4Smrg * Give the driver a chance to act upon the new_state flags. 5547117f1b4Smrg * The driver might plug in different span functions, for example. 5557117f1b4Smrg * Also, this is where the driver can invalidate the state of any 5567117f1b4Smrg * active modules (such as swrast_setup, swrast, tnl, etc). 5577117f1b4Smrg * 5587117f1b4Smrg * Set ctx->NewState to zero to avoid recursion if 5597117f1b4Smrg * Driver.UpdateState() has to call FLUSH_VERTICES(). (fixed?) 5607117f1b4Smrg */ 561c1f859d4Smrg new_state = ctx->NewState | new_prog_state; 5627117f1b4Smrg ctx->NewState = 0; 5637117f1b4Smrg ctx->Driver.UpdateState(ctx, new_state); 5647117f1b4Smrg ctx->Array.NewState = 0; 5657117f1b4Smrg} 5667117f1b4Smrg 5677117f1b4Smrg 5687117f1b4Smrg/* This is the usual entrypoint for state updates: 5697117f1b4Smrg */ 5707117f1b4Smrgvoid 5717117f1b4Smrg_mesa_update_state( GLcontext *ctx ) 5727117f1b4Smrg{ 5737117f1b4Smrg _mesa_lock_context_textures(ctx); 5747117f1b4Smrg _mesa_update_state_locked(ctx); 5757117f1b4Smrg _mesa_unlock_context_textures(ctx); 5767117f1b4Smrg} 577