summaryrefslogtreecommitdiff
path: root/src/mesa/main/state.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main/state.c')
-rw-r--r--src/mesa/main/state.c500
1 files changed, 292 insertions, 208 deletions
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 1cd88a7b73..7071c0ad6f 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -1,4 +1,4 @@
-/* $Id: state.c,v 1.42 2000/11/10 18:31:04 brianp Exp $ */
+/* $Id: state.c,v 1.43 2000/11/13 20:02:56 keithw Exp $ */
/*
* Mesa 3-D graphics library
@@ -747,264 +747,348 @@ void gl_print_enable_flags( const char *msg, GLuint flags )
}
-/*
- * If ctx->NewState is non-zero then this function MUST be called before
- * rendering any primitive. Basically, function pointers and miscellaneous
- * flags are updated to reflect the current state of the state machine.
+/* Note: This routine refers to derived texture attribute values to
+ * compute the ENABLE_TEXMAT flags, but is only called on
+ * _NEW_TEXTURE_MATRIX. On changes to _NEW_TEXTURE, the ENABLE_TEXMAT
+ * flags are updated by _mesa_update_textures(), below.
+ *
+ * If both TEXTURE and TEXTURE_MATRIX change at once, these values
+ * will be computed twice.
*/
-void gl_update_state( GLcontext *ctx )
+static void
+_mesa_update_texture_matrices( GLcontext *ctx )
{
GLuint i;
- if (MESA_VERBOSE & VERBOSE_STATE)
- gl_print_state("", ctx->NewState);
+ ctx->_Enabled &= ~(ENABLE_TEXMAT0 | ENABLE_TEXMAT1 | ENABLE_TEXMAT2);
- if (ctx->NewState & (_NEW_PIXEL|_NEW_COLOR_MATRIX))
- _mesa_update_image_transfer_state(ctx);
+ for (i=0; i < ctx->Const.MaxTextureUnits; i++) {
+ if (ctx->TextureMatrix[i].flags & MAT_DIRTY_ALL_OVER) {
+ gl_matrix_analyze( &ctx->TextureMatrix[i] );
+ ctx->TextureMatrix[i].flags &= ~MAT_DIRTY_DEPENDENTS;
- if (ctx->NewState & _NEW_ARRAY)
- gl_update_client_state( ctx );
+ if (ctx->Texture.Unit[i]._ReallyEnabled &&
+ ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
+ ctx->_Enabled |= ENABLE_TEXMAT0 << i;
+ }
+ }
+}
- if (ctx->NewState & _NEW_TEXTURE_MATRIX) {
- ctx->_Enabled &= ~(ENABLE_TEXMAT0 | ENABLE_TEXMAT1 | ENABLE_TEXMAT2);
- for (i=0; i < ctx->Const.MaxTextureUnits; i++) {
- if (ctx->TextureMatrix[i].flags & MAT_DIRTY_ALL_OVER) {
- gl_matrix_analyze( &ctx->TextureMatrix[i] );
- ctx->TextureMatrix[i].flags &= ~MAT_DIRTY_DEPENDENTS;
+/* Note: This routine refers to derived texture matrix values to
+ * compute the ENABLE_TEXMAT flags, but is only called on
+ * _NEW_TEXTURE. On changes to _NEW_TEXTURE_MATRIX, the ENABLE_TEXMAT
+ * flags are updated by _mesa_update_texture_matrices, above.
+ *
+ * If both TEXTURE and TEXTURE_MATRIX change at once, these values
+ * will be computed twice.
+ */
+static void
+_mesa_update_textures( GLcontext *ctx )
+{
+ GLuint i;
+
+ ctx->Texture._ReallyEnabled = 0;
+ ctx->_Enabled &= ~(ENABLE_TEXGEN0 | ENABLE_TEXGEN1 | ENABLE_TEXGEN2 |
+ ENABLE_TEXMAT0 | ENABLE_TEXMAT1 | ENABLE_TEXMAT2 |
+ ENABLE_TEX0 | ENABLE_TEX1 | ENABLE_TEX2);
- if (ctx->Texture.Unit[i].Enabled &&
- ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
- ctx->_Enabled |= ENABLE_TEXMAT0 << i;
- }
- }
- }
+ gl_update_dirty_texobjs(ctx);
- if (ctx->NewState & _NEW_TEXTURE) {
- ctx->Texture._MultiTextureEnabled = GL_FALSE;
- ctx->Texture._NeedNormals = GL_FALSE;
- gl_update_dirty_texobjs(ctx);
- ctx->_Enabled &= ~(ENABLE_TEXGEN0 | ENABLE_TEXGEN1 | ENABLE_TEXGEN2);
- ctx->Texture._ReallyEnabled = 0;
+ for (i=0; i < ctx->Const.MaxTextureUnits; i++) {
+
+ ctx->Texture.Unit[i]._ReallyEnabled = 0;
- for (i=0; i < ctx->Const.MaxTextureUnits; i++) {
- if (ctx->Texture.Unit[i].Enabled) {
- gl_update_texture_unit( ctx, &ctx->Texture.Unit[i] );
+ if (ctx->Texture.Unit[i].Enabled) {
- ctx->Texture._ReallyEnabled |=
- ctx->Texture.Unit[i]._ReallyEnabled << (i * 4);
+ gl_update_texture_unit( ctx, &ctx->Texture.Unit[i] );
- if (ctx->Texture.Unit[i]._GenFlags != 0) {
- ctx->_Enabled |= ENABLE_TEXGEN0 << i;
+ if (ctx->Texture.Unit[i]._ReallyEnabled) {
+ GLuint flag = ctx->Texture.Unit[i]._ReallyEnabled << (i * 4);
- if (ctx->Texture.Unit[i]._GenFlags & TEXGEN_NEED_NORMALS) {
- ctx->Texture._NeedNormals = GL_TRUE;
- ctx->Texture._NeedEyeCoords = GL_TRUE;
- }
+ ctx->Texture._ReallyEnabled |= flag;
+ ctx->_Enabled |= flag;
- if (ctx->Texture.Unit[i]._GenFlags & TEXGEN_NEED_EYE_COORD) {
- ctx->Texture._NeedEyeCoords = GL_TRUE;
- }
+ if (ctx->Texture.Unit[i]._GenFlags) {
+ ctx->_Enabled |= ENABLE_TEXGEN0 << i;
+ ctx->Texture._GenFlags |= ctx->Texture.Unit[i]._GenFlags;
}
- if (i > 0 && ctx->Texture.Unit[i]._ReallyEnabled) {
- ctx->Texture._MultiTextureEnabled = GL_TRUE;
- }
+ if (ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
+ ctx->_Enabled |= ENABLE_TEXMAT0 << i;
}
- else {
- ctx->Texture.Unit[i]._ReallyEnabled = 0;
- }
}
- ctx->_Enabled = ((ctx->_Enabled & ~ENABLE_TEX_ANY) |
- ctx->Texture._ReallyEnabled);
- ctx->_NeedNormals = (ctx->Light.Enabled || ctx->Texture._NeedNormals);
}
+ ctx->_NeedNormals &= ~NEED_NORMALS_TEXGEN;
+ ctx->_NeedEyeCoords &= ~NEED_EYE_TEXGEN;
- if (ctx->NewState & (_NEW_BUFFERS|_NEW_SCISSOR)) {
- /* update scissor region */
- ctx->DrawBuffer->Xmin = 0;
- ctx->DrawBuffer->Ymin = 0;
- ctx->DrawBuffer->Xmax = ctx->DrawBuffer->Width;
- ctx->DrawBuffer->Ymax = ctx->DrawBuffer->Height;
- if (ctx->Scissor.Enabled) {
- if (ctx->Scissor.X > ctx->DrawBuffer->Xmin) {
- ctx->DrawBuffer->Xmin = ctx->Scissor.X;
- }
- if (ctx->Scissor.Y > ctx->DrawBuffer->Ymin) {
- ctx->DrawBuffer->Ymin = ctx->Scissor.Y;
- }
- if (ctx->Scissor.X + ctx->Scissor.Width < ctx->DrawBuffer->Xmax) {
- ctx->DrawBuffer->Xmax = ctx->Scissor.X + ctx->Scissor.Width;
- }
- if (ctx->Scissor.Y + ctx->Scissor.Height < ctx->DrawBuffer->Ymax) {
- ctx->DrawBuffer->Ymax = ctx->Scissor.Y + ctx->Scissor.Height;
- }
- }
+ if (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS) {
+ ctx->_NeedNormals |= NEED_NORMALS_TEXGEN;
+ ctx->_NeedEyeCoords |= NEED_EYE_TEXGEN;
+ }
+
+ if (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD) {
+ ctx->_NeedEyeCoords |= NEED_EYE_TEXGEN;
}
+}
- if (ctx->NewState & _NEW_LIGHT) {
- ctx->_TriangleCaps &= ~(DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
- if (ctx->Light.Enabled) {
- if (ctx->Light.Model.TwoSide)
- ctx->_TriangleCaps |= (DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
- gl_update_lighting(ctx);
+static void
+_mesa_update_polygon( GLcontext *ctx )
+{
+ ctx->_TriangleCaps &= ~DD_TRI_CULL_FRONT_BACK;
+
+ /* Setup CullBits bitmask */
+ if (ctx->Polygon.CullFlag) {
+ switch(ctx->Polygon.CullFaceMode) {
+ case GL_BACK:
+ ctx->Polygon._CullBits = 1;
+ break;
+ case GL_FRONT:
+ ctx->Polygon._CullBits = 2;
+ break;
+ default:
+ case GL_FRONT_AND_BACK:
+ ctx->Polygon._CullBits = 0;
+ ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK;
+ break;
}
}
+ else {
+ ctx->Polygon._CullBits = 3;
+ }
- if (ctx->NewState & (_NEW_POLYGON | _NEW_LIGHT)) {
-
-
- if (ctx->NewState & _NEW_POLYGON) {
- ctx->_TriangleCaps &= ~DD_TRI_CULL_FRONT_BACK;
-
- /* Setup CullBits bitmask */
- if (ctx->Polygon.CullFlag) {
- ctx->_backface_sign = 1;
- switch(ctx->Polygon.CullFaceMode) {
- case GL_BACK:
- if(ctx->Polygon.FrontFace==GL_CCW)
- ctx->_backface_sign = -1;
- ctx->Polygon._CullBits = 1;
- break;
- case GL_FRONT:
- if(ctx->Polygon.FrontFace!=GL_CCW)
- ctx->_backface_sign = -1;
- ctx->Polygon._CullBits = 2;
- break;
- default:
- case GL_FRONT_AND_BACK:
- ctx->_backface_sign = 0;
- ctx->Polygon._CullBits = 0;
- ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK;
- break;
- }
- }
- else {
- ctx->Polygon._CullBits = 3;
- ctx->_backface_sign = 0;
- }
+ /* Any Polygon offsets enabled? */
+ ctx->_TriangleCaps &= ~DD_TRI_OFFSET;
- /* Any Polygon offsets enabled? */
- ctx->_TriangleCaps &= ~DD_TRI_OFFSET;
+ if (ctx->Polygon.OffsetPoint ||
+ ctx->Polygon.OffsetLine ||
+ ctx->Polygon.OffsetFill)
+ ctx->_TriangleCaps |= DD_TRI_OFFSET;
+}
- if (ctx->Polygon.OffsetPoint ||
- ctx->Polygon.OffsetLine ||
- ctx->Polygon.OffsetFill)
- ctx->_TriangleCaps |= DD_TRI_OFFSET;
- }
+static void
+_mesa_calculate_model_project_matrix( GLcontext *ctx )
+{
+ if (!ctx->_NeedEyeCoords) {
+ gl_matrix_mul( &ctx->_ModelProjectMatrix,
+ &ctx->ProjectionMatrix,
+ &ctx->ModelView );
+
+ gl_matrix_analyze( &ctx->_ModelProjectMatrix );
}
+}
- if (ctx->NewState & (_NEW_LIGHT|
- _NEW_TEXTURE|
- _NEW_FOG|
- _NEW_POLYGON))
- gl_update_clipmask(ctx);
+static void
+_mesa_update_modelview_scale( GLcontext *ctx )
+{
+ ctx->_ModelViewInvScale = 1.0F;
+ if (ctx->ModelView.flags & (MAT_FLAG_UNIFORM_SCALE |
+ MAT_FLAG_GENERAL_SCALE |
+ MAT_FLAG_GENERAL_3D |
+ MAT_FLAG_GENERAL) ) {
+ const GLfloat *m = ctx->ModelView.inv;
+ GLfloat f = m[2] * m[2] + m[6] * m[6] + m[10] * m[10];
+ if (f < 1e-12) f = 1.0;
+ if (ctx->_NeedEyeCoords)
+ ctx->_ModelViewInvScale = 1.0/GL_SQRT(f);
+ else
+ ctx->_ModelViewInvScale = GL_SQRT(f);
+ }
+}
- if (ctx->NewState & ctx->Driver.UpdateStateNotify)
+
+/* Bring uptodate any state that relies on _NeedEyeCoords.
+ */
+static void
+_mesa_update_tnl_spaces( GLcontext *ctx, GLuint oldneedeyecoords )
+{
+ /* Check if the truth-value interpretations of the bitfields have
+ * changed:
+ */
+ if ((oldneedeyecoords == 0) != (ctx->_NeedEyeCoords == 0))
{
- /*
- * Here the driver sets up all the ctx->Driver function pointers to
- * it's specific, private functions.
+ /* Recalculate all state that depends on _NeedEyeCoords.
*/
- ctx->Driver.UpdateState(ctx);
- gl_set_render_vb_function(ctx); /* fix me */
+ _mesa_update_modelview_scale(ctx);
+ _mesa_calculate_model_project_matrix(ctx);
+ gl_update_normal_transform( ctx );
+ gl_compute_light_positions( ctx );
+
+ if (ctx->Driver.LightingSpaceChange)
+ ctx->Driver.LightingSpaceChange( ctx );
}
+ else
+ {
+ GLuint new_state = ctx->NewState;
- /* Should only be calc'd when !need_eye_coords and not culling.
- */
- if (ctx->NewState & (_NEW_MODELVIEW|_NEW_PROJECTION)) {
- if (ctx->NewState & _NEW_MODELVIEW) {
- gl_matrix_analyze( &ctx->ModelView );
- ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
+ /* Recalculate that same state if and only if it has been
+ * invalidated by other statechanges.
+ */
+ if (new_state & _NEW_MODELVIEW)
+ _mesa_update_modelview_scale(ctx);
+
+ if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
+ _mesa_calculate_model_project_matrix(ctx);
+
+ if (new_state & _TNL_NEW_NORMAL_TRANSFORM)
+ gl_update_normal_transform( ctx ); /* references _ModelViewInvScale */
+
+ if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW))
+ gl_compute_light_positions( ctx );
+ }
+}
+
+
+static void
+_mesa_update_drawbuffer( GLcontext *ctx )
+{
+ ctx->DrawBuffer->_Xmin = 0;
+ ctx->DrawBuffer->_Ymin = 0;
+ ctx->DrawBuffer->_Xmax = ctx->DrawBuffer->Width;
+ ctx->DrawBuffer->_Ymax = ctx->DrawBuffer->Height;
+ if (ctx->Scissor.Enabled) {
+ if (ctx->Scissor.X > ctx->DrawBuffer->_Xmin) {
+ ctx->DrawBuffer->_Xmin = ctx->Scissor.X;
+ }
+ if (ctx->Scissor.Y > ctx->DrawBuffer->_Ymin) {
+ ctx->DrawBuffer->_Ymin = ctx->Scissor.Y;
+ }
+ if (ctx->Scissor.X + ctx->Scissor.Width < ctx->DrawBuffer->_Xmax) {
+ ctx->DrawBuffer->_Xmax = ctx->Scissor.X + ctx->Scissor.Width;
}
+ if (ctx->Scissor.Y + ctx->Scissor.Height < ctx->DrawBuffer->_Ymax) {
+ ctx->DrawBuffer->_Ymax = ctx->Scissor.Y + ctx->Scissor.Height;
+ }
+ }
+}
- if (ctx->NewState & _NEW_PROJECTION) {
- gl_matrix_analyze( &ctx->ProjectionMatrix );
- ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
- if (ctx->Transform._AnyClip) {
- gl_update_userclip( ctx );
+/* NOTE: This routine references Tranform attribute values to compute
+ * userclip positions in clip space, but is only called on
+ * _NEW_PROJECTION. The _mesa_ClipPlane() function keeps these values
+ * uptodate across changes to the Transform attributes.
+ */
+static void
+_mesa_update_projection( GLcontext *ctx )
+{
+ gl_matrix_analyze( &ctx->ProjectionMatrix );
+
+ /* Recompute clip plane positions in clipspace. This is also done
+ * in _mesa_ClipPlane().
+ */
+ if (ctx->Transform._AnyClip) {
+ GLuint p;
+ for (p = 0 ; p < MAX_CLIP_PLANES ; p++) {
+ if (ctx->Transform.ClipEnabled[p]) {
+ gl_transform_vector( ctx->Transform._ClipUserPlane[p],
+ ctx->Transform.EyeUserPlane[p],
+ ctx->ProjectionMatrix.inv );
}
}
-
- gl_calculate_model_project_matrix( ctx );
}
+}
+
+
+
+
+/*
+ * If ctx->NewState is non-zero then this function MUST be called before
+ * rendering any primitive. Basically, function pointers and miscellaneous
+ * flags are updated to reflect the current state of the state machine.
+ *
+ * Special care is taken with the derived value _NeedEyeCoords. These
+ * is a bitflag which is updated with information from a number of
+ * attribute groups (MODELVIEW, LIGHT, TEXTURE). A lot of derived
+ * state references this value, and must be treated with care to
+ * ensure that updates are done correctly. All state dependent on
+ * _NeedEyeCoords is calculated from within _mesa_update_tnl_spaces(),
+ * and from nowhere else.
+ */
+void gl_update_state( GLcontext *ctx )
+{
+ GLuint new_state = ctx->NewState;
+ GLuint oldneedeyecoords = ctx->_NeedEyeCoords;
+
+ if (MESA_VERBOSE & VERBOSE_STATE)
+ gl_print_state("", new_state);
+
+ if (new_state & _NEW_MODELVIEW)
+ gl_matrix_analyze( &ctx->ModelView );
+
+ if (new_state & _NEW_PROJECTION)
+ _mesa_update_projection( ctx );
- if (ctx->NewState & _NEW_COLOR_MATRIX) {
+ if (new_state & _NEW_TEXTURE_MATRIX)
+ _mesa_update_texture_matrices( ctx );
+
+ if (new_state & _NEW_COLOR_MATRIX)
gl_matrix_analyze( &ctx->ColorMatrix );
- }
+
+ /* References ColorMatrix.type (derived above).
+ */
+ if (new_state & (_NEW_PIXEL|_NEW_COLOR_MATRIX))
+ _mesa_update_image_transfer_state(ctx);
+
+ if (new_state & _NEW_ARRAY)
+ gl_update_client_state( ctx );
- /* Figure out whether we can light in object space or not. If we
- * can, find the current positions of the lights in object space
+ /* Contributes to NeedEyeCoords, NeedNormals.
*/
- if ((ctx->_Enabled & (ENABLE_POINT_ATTEN | ENABLE_LIGHT | ENABLE_FOG |
- ENABLE_TEXGEN0 | ENABLE_TEXGEN1 | ENABLE_TEXGEN2)) &&
- (ctx->NewState & (_NEW_LIGHT |
- _NEW_TEXTURE |
- _NEW_FOG |
- _NEW_TRANSFORM |
- _NEW_MODELVIEW |
- _NEW_PROJECTION |
- _NEW_POINT |
- _NEW_RENDERMODE |
- _NEW_TRANSFORM)))
- {
- GLboolean oldcoord, oldnorm;
-
- oldcoord = ctx->_NeedEyeCoords;
- oldnorm = ctx->_NeedEyeNormals;
-
- ctx->_NeedNormals = (ctx->Light.Enabled || ctx->Texture._NeedNormals);
- ctx->_NeedEyeCoords = (ctx->Fog.Enabled || ctx->Point._Attenuated);
- ctx->_NeedEyeNormals = GL_FALSE;
-
- if (ctx->Light.Enabled) {
- if ((ctx->Light._Flags & LIGHT_POSITIONAL) ||
- ctx->Light._NeedVertices ||
- !TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_LENGTH_PRESERVING)) {
- /* Need length for attenuation or need angle for spotlights
- * or non-uniform scale matrix
- */
- ctx->_NeedEyeCoords = GL_TRUE;
- }
- ctx->_NeedEyeNormals = ctx->_NeedEyeCoords;
- }
- if (ctx->Texture._ReallyEnabled || ctx->RenderMode==GL_FEEDBACK) {
- if (ctx->Texture._NeedEyeCoords) ctx->_NeedEyeCoords = GL_TRUE;
- if (ctx->Texture._NeedNormals)
- ctx->_NeedNormals = ctx->_NeedEyeNormals = GL_TRUE;
- }
+ if (new_state & _NEW_TEXTURE)
+ _mesa_update_textures( ctx );
- if (ctx->_NeedEyeCoords)
- ctx->_vb_proj_matrix = &ctx->ProjectionMatrix;
- else
- ctx->_vb_proj_matrix = &ctx->_ModelProjectMatrix;
+ if (new_state & (_NEW_BUFFERS|_NEW_SCISSOR))
+ _mesa_update_drawbuffer( ctx );
- if (ctx->Light.Enabled) {
- gl_update_lighting_function(ctx);
+ if (new_state & _NEW_POLYGON)
+ _mesa_update_polygon( ctx );
- if ( (ctx->NewState & _NEW_LIGHT) ||
- ((ctx->NewState & (_NEW_MODELVIEW|_NEW_PROJECTION)) &&
- !ctx->_NeedEyeCoords) ||
- oldcoord != ctx->_NeedEyeCoords ||
- oldnorm != ctx->_NeedEyeNormals) {
- gl_compute_light_positions(ctx);
- }
+ /* Contributes to NeedEyeCoords, NeedNormals.
+ */
+ if (new_state & _NEW_LIGHT)
+ gl_update_lighting( ctx );
- ctx->_rescale_factor = 1.0F;
- if (ctx->ModelView.flags & (MAT_FLAG_UNIFORM_SCALE |
- MAT_FLAG_GENERAL_SCALE |
- MAT_FLAG_GENERAL_3D |
- MAT_FLAG_GENERAL) ) {
- const GLfloat *m = ctx->ModelView.inv;
- const GLfloat f = m[2] * m[2] + m[6] * m[6] + m[10] * m[10];
- if (f > 1e-12 && (f - 1.0) * (f - 1.0) > 1e-12)
- ctx->_rescale_factor = 1.0 / GL_SQRT(f);
- }
- }
+ if (new_state & (_NEW_LIGHT|_NEW_TEXTURE|_NEW_FOG|
+ _DD_NEW_TRI_LIGHT_TWOSIDE |
+ _DD_NEW_SEPERATE_SPECULAR |
+ _DD_NEW_TRI_UNFILLED ))
+ gl_update_clipmask(ctx);
+
+ /* We can light in object space if the modelview matrix preserves
+ * lengths and relative angles.
+ */
+ if (new_state & (_NEW_MODELVIEW|_NEW_LIGHT)) {
+ ctx->_NeedEyeCoords &= ~NEED_EYE_LIGHT_MODELVIEW;
+ if (ctx->Light.Enabled &&
+ !TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_LENGTH_PRESERVING))
+ ctx->_NeedEyeCoords |= NEED_EYE_LIGHT_MODELVIEW;
+ }
- gl_update_normal_transform( ctx );
+ /* ctx->_NeedEyeCoords and ctx->_NeedEyeNormals are now uptodate.
+ *
+ * If the truth value of either has changed, update for the new
+ * lighting space and recompute the positions of lights and the
+ * normal transform.
+ *
+ * If the lighting space hasn't changed, may still need to recompute
+ * light positions & normal transforms for other reasons.
+ */
+ if (new_state & (_NEW_MODELVIEW |
+ _NEW_PROJECTION |
+ _TNL_NEW_NORMAL_TRANSFORM |
+ _NEW_LIGHT |
+ _TNL_NEW_NEED_EYE_COORDS))
+ _mesa_update_tnl_spaces( ctx, oldneedeyecoords );
+
+ if (new_state & ctx->Driver.UpdateStateNotify)
+ {
+ /*
+ * Here the driver sets up all the ctx->Driver function pointers to
+ * it's specific, private functions.
+ */
+ ctx->Driver.UpdateState(ctx);
+ gl_set_render_vb_function(ctx); /* XXX: remove this mechanism */
}
gl_update_pipelines(ctx);