+static void
+pop_enable_group(GLcontext *ctx, const struct gl_enable_attrib *enable)
+{
+ GLuint i;
+
+#define TEST_AND_UPDATE(VALUE, NEWVALUE, ENUM) \
+ if ((VALUE) != (NEWVALUE)) { \
+ _mesa_set_enable( ctx, ENUM, (NEWVALUE) ); \
+ }
+
+ TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST);
+ TEST_AND_UPDATE(ctx->Color.BlendEnabled, enable->Blend, GL_BLEND);
+
+ for (i=0;i<MAX_CLIP_PLANES;i++) {
+ const GLuint mask = 1 << i;
+ if ((ctx->Transform.ClipPlanesEnabled & mask) != (enable->ClipPlanes & mask))
+ _mesa_set_enable(ctx, (GLenum) (GL_CLIP_PLANE0 + i),
+ (GLboolean) ((enable->ClipPlanes & mask) ? GL_TRUE : GL_FALSE));
+ }
+
+ TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial,
+ GL_COLOR_MATERIAL);
+ TEST_AND_UPDATE(ctx->Pixel.ColorTableEnabled, enable->ColorTable,
+ GL_COLOR_TABLE);
+ TEST_AND_UPDATE(ctx->Pixel.PostColorMatrixColorTableEnabled,
+ enable->PostColorMatrixColorTable,
+ GL_POST_COLOR_MATRIX_COLOR_TABLE);
+ TEST_AND_UPDATE(ctx->Pixel.PostConvolutionColorTableEnabled,
+ enable->PostConvolutionColorTable,
+ GL_POST_CONVOLUTION_COLOR_TABLE);
+ TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE);
+ TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST);
+ TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER);
+ TEST_AND_UPDATE(ctx->Pixel.Convolution1DEnabled, enable->Convolution1D,
+ GL_CONVOLUTION_1D);
+ TEST_AND_UPDATE(ctx->Pixel.Convolution2DEnabled, enable->Convolution2D,
+ GL_CONVOLUTION_2D);
+ TEST_AND_UPDATE(ctx->Pixel.Separable2DEnabled, enable->Separable2D,
+ GL_SEPARABLE_2D);
+ TEST_AND_UPDATE(ctx->Fog.Enabled, enable->Fog, GL_FOG);
+ TEST_AND_UPDATE(ctx->Light.Enabled, enable->Lighting, GL_LIGHTING);
+ TEST_AND_UPDATE(ctx->Line.SmoothFlag, enable->LineSmooth, GL_LINE_SMOOTH);
+ TEST_AND_UPDATE(ctx->Line.StippleFlag, enable->LineStipple,
+ GL_LINE_STIPPLE);
+ TEST_AND_UPDATE(ctx->Color.IndexLogicOpEnabled, enable->IndexLogicOp,
+ GL_INDEX_LOGIC_OP);
+ TEST_AND_UPDATE(ctx->Color.ColorLogicOpEnabled, enable->ColorLogicOp,
+ GL_COLOR_LOGIC_OP);
+
+ TEST_AND_UPDATE(ctx->Eval.Map1Color4, enable->Map1Color4, GL_MAP1_COLOR_4);
+ TEST_AND_UPDATE(ctx->Eval.Map1Index, enable->Map1Index, GL_MAP1_INDEX);
+ TEST_AND_UPDATE(ctx->Eval.Map1Normal, enable->Map1Normal, GL_MAP1_NORMAL);
+ TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord1, enable->Map1TextureCoord1,
+ GL_MAP1_TEXTURE_COORD_1);
+ TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord2, enable->Map1TextureCoord2,
+ GL_MAP1_TEXTURE_COORD_2);
+ TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord3, enable->Map1TextureCoord3,
+ GL_MAP1_TEXTURE_COORD_3);
+ TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord4, enable->Map1TextureCoord4,
+ GL_MAP1_TEXTURE_COORD_4);
+ TEST_AND_UPDATE(ctx->Eval.Map1Vertex3, enable->Map1Vertex3,
+ GL_MAP1_VERTEX_3);
+ TEST_AND_UPDATE(ctx->Eval.Map1Vertex4, enable->Map1Vertex4,
+ GL_MAP1_VERTEX_4);
+ for (i = 0; i < 16; i++) {
+ TEST_AND_UPDATE(ctx->Eval.Map1Attrib[i], enable->Map1Attrib[i],
+ GL_MAP1_VERTEX_ATTRIB0_4_NV + i);
+ }
+
+ TEST_AND_UPDATE(ctx->Eval.Map2Color4, enable->Map2Color4, GL_MAP2_COLOR_4);
+ TEST_AND_UPDATE(ctx->Eval.Map2Index, enable->Map2Index, GL_MAP2_INDEX);
+ TEST_AND_UPDATE(ctx->Eval.Map2Normal, enable->Map2Normal, GL_MAP2_NORMAL);
+ TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord1, enable->Map2TextureCoord1,
+ GL_MAP2_TEXTURE_COORD_1);
+ TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord2, enable->Map2TextureCoord2,
+ GL_MAP2_TEXTURE_COORD_2);
+ TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord3, enable->Map2TextureCoord3,
+ GL_MAP2_TEXTURE_COORD_3);
+ TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord4, enable->Map2TextureCoord4,
+ GL_MAP2_TEXTURE_COORD_4);
+ TEST_AND_UPDATE(ctx->Eval.Map2Vertex3, enable->Map2Vertex3,
+ GL_MAP2_VERTEX_3);
+ TEST_AND_UPDATE(ctx->Eval.Map2Vertex4, enable->Map2Vertex4,
+ GL_MAP2_VERTEX_4);
+ for (i = 0; i < 16; i++) {
+ TEST_AND_UPDATE(ctx->Eval.Map2Attrib[i], enable->Map2Attrib[i],
+ GL_MAP2_VERTEX_ATTRIB0_4_NV + i);
+ }
+
+ TEST_AND_UPDATE(ctx->Eval.AutoNormal, enable->AutoNormal, GL_AUTO_NORMAL);
+ TEST_AND_UPDATE(ctx->Transform.Normalize, enable->Normalize, GL_NORMALIZE);
+ TEST_AND_UPDATE(ctx->Transform.RescaleNormals, enable->RescaleNormals,
+ GL_RESCALE_NORMAL_EXT);
+ TEST_AND_UPDATE(ctx->Transform.RasterPositionUnclipped,
+ enable->RasterPositionUnclipped,
+ GL_RASTER_POSITION_UNCLIPPED_IBM);
+ TEST_AND_UPDATE(ctx->Pixel.PixelTextureEnabled, enable->PixelTexture,
+ GL_POINT_SMOOTH);
+ TEST_AND_UPDATE(ctx->Point.SmoothFlag, enable->PointSmooth,
+ GL_POINT_SMOOTH);
+ if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite) {
+ TEST_AND_UPDATE(ctx->Point.PointSprite, enable->PointSprite,
+ GL_POINT_SPRITE_NV);
+ }
+ TEST_AND_UPDATE(ctx->Polygon.OffsetPoint, enable->PolygonOffsetPoint,
+ GL_POLYGON_OFFSET_POINT);
+ TEST_AND_UPDATE(ctx->Polygon.OffsetLine, enable->PolygonOffsetLine,
+ GL_POLYGON_OFFSET_LINE);
+ TEST_AND_UPDATE(ctx->Polygon.OffsetFill, enable->PolygonOffsetFill,
+ GL_POLYGON_OFFSET_FILL);
+ TEST_AND_UPDATE(ctx->Polygon.SmoothFlag, enable->PolygonSmooth,
+ GL_POLYGON_SMOOTH);
+ TEST_AND_UPDATE(ctx->Polygon.StippleFlag, enable->PolygonStipple,
+ GL_POLYGON_STIPPLE);
+ TEST_AND_UPDATE(ctx->Scissor.Enabled, enable->Scissor, GL_SCISSOR_TEST);
+ TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST);
+ /* XXX two-sided stencil */
+ TEST_AND_UPDATE(ctx->Multisample.Enabled, enable->MultisampleEnabled,
+ GL_MULTISAMPLE_ARB);
+ TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage,
+ enable->SampleAlphaToCoverage,
+ GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
+ TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToOne,
+ enable->SampleAlphaToOne,
+ GL_SAMPLE_ALPHA_TO_ONE_ARB);
+ TEST_AND_UPDATE(ctx->Multisample.SampleCoverage,
+ enable->SampleCoverage,
+ GL_SAMPLE_COVERAGE_ARB);
+ TEST_AND_UPDATE(ctx->Multisample.SampleCoverageInvert,
+ enable->SampleCoverageInvert,
+ GL_SAMPLE_COVERAGE_INVERT_ARB);
+ /* GL_NV_vertex_program */
+ TEST_AND_UPDATE(ctx->VertexProgram.Enabled,
+ enable->VertexProgram,
+ GL_VERTEX_PROGRAM_NV);
+ TEST_AND_UPDATE(ctx->VertexProgram.PointSizeEnabled,
+ enable->VertexProgramPointSize,
+ GL_VERTEX_PROGRAM_POINT_SIZE_NV);
+ TEST_AND_UPDATE(ctx->VertexProgram.TwoSideEnabled,
+ enable->VertexProgramTwoSide,
+ GL_VERTEX_PROGRAM_TWO_SIDE_NV);
+
+#undef TEST_AND_UPDATE
+
+ /* texture unit enables */
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+ if (ctx->Texture.Unit[i].Enabled != enable->Texture[i]) {
+ ctx->Texture.Unit[i].Enabled = enable->Texture[i];
+ if (ctx->Driver.Enable) {
+ if (ctx->Driver.ActiveTexture) {
+ (*ctx->Driver.ActiveTexture)(ctx, i);
+ }
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_1D,
+ (GLboolean) (enable->Texture[i] & TEXTURE_1D_BIT) );
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_2D,
+ (GLboolean) (enable->Texture[i] & TEXTURE_2D_BIT) );
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_3D,
+ (GLboolean) (enable->Texture[i] & TEXTURE_3D_BIT) );
+ if (ctx->Extensions.ARB_texture_cube_map)
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_CUBE_MAP_ARB,
+ (GLboolean) (enable->Texture[i] & TEXTURE_CUBE_BIT) );
+ if (ctx->Extensions.NV_texture_rectangle)
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_RECTANGLE_NV,
+ (GLboolean) (enable->Texture[i] & TEXTURE_RECT_BIT) );
+ }
+ }
+
+ if (ctx->Texture.Unit[i].TexGenEnabled != enable->TexGen[i]) {
+ ctx->Texture.Unit[i].TexGenEnabled = enable->TexGen[i];
+ if (ctx->Driver.Enable) {
+ if (ctx->Driver.ActiveTexture) {
+ (*ctx->Driver.ActiveTexture)(ctx, i);
+ }
+ if (enable->TexGen[i] & S_BIT)
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_TRUE);
+ else
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_FALSE);
+ if (enable->TexGen[i] & T_BIT)
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_TRUE);
+ else
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_FALSE);
+ if (enable->TexGen[i] & R_BIT)
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_TRUE);
+ else
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_FALSE);
+ if (enable->TexGen[i] & Q_BIT)
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_TRUE);
+ else
+ (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_FALSE);
+ }
+ }
+
+ /* GL_SGI_texture_color_table */
+ ctx->Texture.Unit[i].ColorTableEnabled = enable->TextureColorTable[i];
+ }
+
+ if (ctx->Driver.ActiveTexture) {
+ (*ctx->Driver.ActiveTexture)(ctx, ctx->Texture.CurrentUnit);
+ }
+}
+
+
+static void
+pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib)
+{
+ GLuint u;
+
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+ const struct gl_texture_unit *unit = &texAttrib->Unit[u];
+ GLuint i;
+
+ _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + u);
+ _mesa_set_enable(ctx, GL_TEXTURE_1D,
+ (GLboolean) (unit->Enabled & TEXTURE_1D_BIT ? GL_TRUE : GL_FALSE));
+ _mesa_set_enable(ctx, GL_TEXTURE_2D,
+ (GLboolean) (unit->Enabled & TEXTURE_2D_BIT ? GL_TRUE : GL_FALSE));
+ _mesa_set_enable(ctx, GL_TEXTURE_3D,
+ (GLboolean) (unit->Enabled & TEXTURE_3D_BIT ? GL_TRUE : GL_FALSE));
+ if (ctx->Extensions.ARB_texture_cube_map) {
+ _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP_ARB,
+ (GLboolean) (unit->Enabled & TEXTURE_CUBE_BIT ? GL_TRUE : GL_FALSE));
+ }
+ if (ctx->Extensions.NV_texture_rectangle) {
+ _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE_NV,
+ (GLboolean) (unit->Enabled & TEXTURE_RECT_BIT ? GL_TRUE : GL_FALSE));
+ }
+ if (ctx->Extensions.SGI_texture_color_table) {
+ _mesa_set_enable(ctx, GL_TEXTURE_COLOR_TABLE_SGI,
+ unit->ColorTableEnabled);
+ }
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->EnvMode);
+ _mesa_TexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, unit->EnvColor);
+ _mesa_TexGeni(GL_S, GL_TEXTURE_GEN_MODE, unit->GenModeS);
+ _mesa_TexGeni(GL_T, GL_TEXTURE_GEN_MODE, unit->GenModeT);
+ _mesa_TexGeni(GL_R, GL_TEXTURE_GEN_MODE, unit->GenModeR);
+ _mesa_TexGeni(GL_Q, GL_TEXTURE_GEN_MODE, unit->GenModeQ);
+ _mesa_TexGenfv(GL_S, GL_OBJECT_PLANE, unit->ObjectPlaneS);
+ _mesa_TexGenfv(GL_T, GL_OBJECT_PLANE, unit->ObjectPlaneT);
+ _mesa_TexGenfv(GL_R, GL_OBJECT_PLANE, unit->ObjectPlaneR);
+ _mesa_TexGenfv(GL_Q, GL_OBJECT_PLANE, unit->ObjectPlaneQ);
+ _mesa_TexGenfv(GL_S, GL_EYE_PLANE, unit->EyePlaneS);
+ _mesa_TexGenfv(GL_T, GL_EYE_PLANE, unit->EyePlaneT);
+ _mesa_TexGenfv(GL_R, GL_EYE_PLANE, unit->EyePlaneR);
+ _mesa_TexGenfv(GL_Q, GL_EYE_PLANE, unit->EyePlaneQ);
+ if (ctx->Extensions.EXT_texture_lod_bias) {
+ _mesa_TexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
+ GL_TEXTURE_LOD_BIAS_EXT, unit->LodBias);
+ }
+ if (ctx->Extensions.EXT_texture_env_combine ||
+ ctx->Extensions.ARB_texture_env_combine) {
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,
+ unit->Combine.ModeRGB);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,
+ unit->Combine.ModeA);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB,
+ unit->Combine.SourceRGB[0]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB,
+ unit->Combine.SourceRGB[1]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB,
+ unit->Combine.SourceRGB[2]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA,
+ unit->Combine.SourceA[0]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA,
+ unit->Combine.SourceA[1]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA,
+ unit->Combine.SourceA[2]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB,
+ unit->Combine.OperandRGB[0]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB,
+ unit->Combine.OperandRGB[1]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB,
+ unit->Combine.OperandRGB[2]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA,
+ unit->Combine.OperandA[0]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA,
+ unit->Combine.OperandA[1]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA,
+ unit->Combine.OperandA[2]);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE,
+ 1 << unit->Combine.ScaleShiftRGB);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE,
+ 1 << unit->Combine.ScaleShiftA);
+ }
+
+ /* Restore texture object state */
+ for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
+ GLenum target = 0;
+ const struct gl_texture_object *obj = NULL;
+ GLfloat bordColor[4];
+
+ switch (i) {
+ case 0:
+ target = GL_TEXTURE_1D;
+ obj = &unit->Saved1D;
+ break;
+ case 1:
+ target = GL_TEXTURE_2D;
+ obj = &unit->Saved2D;
+ break;
+ case 2:
+ target = GL_TEXTURE_3D;
+ obj = &unit->Saved3D;
+ break;
+ case 3:
+ if (!ctx->Extensions.ARB_texture_cube_map)
+ continue;
+ target = GL_TEXTURE_CUBE_MAP_ARB;
+ obj = &unit->SavedCubeMap;
+ break;
+ case 4:
+ if (!ctx->Extensions.NV_texture_rectangle)
+ continue;
+ target = GL_TEXTURE_RECTANGLE_NV;
+ obj = &unit->SavedRect;
+ break;
+ default:
+ ; /* silence warnings */
+ }
+
+ _mesa_BindTexture(target, obj->Name);
+
+ bordColor[0] = CHAN_TO_FLOAT(obj->BorderColor[0]);
+ bordColor[1] = CHAN_TO_FLOAT(obj->BorderColor[1]);
+ bordColor[2] = CHAN_TO_FLOAT(obj->BorderColor[2]);
+ bordColor[3] = CHAN_TO_FLOAT(obj->BorderColor[3]);
+
+ _mesa_TexParameterf(target, GL_TEXTURE_PRIORITY, obj->Priority);
+ _mesa_TexParameterfv(target, GL_TEXTURE_BORDER_COLOR, bordColor);
+ _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, obj->WrapS);
+ _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, obj->WrapT);
+ _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, obj->WrapR);
+ _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, obj->MinFilter);
+ _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, obj->MagFilter);
+ _mesa_TexParameterf(target, GL_TEXTURE_MIN_LOD, obj->MinLod);
+ _mesa_TexParameterf(target, GL_TEXTURE_MAX_LOD, obj->MaxLod);
+ _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, obj->BaseLevel);
+ _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, obj->MaxLevel);
+ if (ctx->Extensions.EXT_texture_filter_anisotropic) {
+ _mesa_TexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT,
+ obj->MaxAnisotropy);
+ }
+ if (ctx->Extensions.SGIX_shadow) {
+ _mesa_TexParameteri(target, GL_TEXTURE_COMPARE_SGIX,
+ obj->CompareFlag);
+ _mesa_TexParameteri(target, GL_TEXTURE_COMPARE_OPERATOR_SGIX,
+ obj->CompareOperator);
+ }
+ if (ctx->Extensions.SGIX_shadow_ambient) {
+ _mesa_TexParameterf(target, GL_SHADOW_AMBIENT_SGIX,
+ obj->ShadowAmbient);
+ }
+
+ }
+ }
+ _mesa_ActiveTextureARB(GL_TEXTURE0_ARB
+ + texAttrib->CurrentUnit);
+
+ /* "un-bump" the texture object reference counts. We did that so they
+ * wouldn't inadvertantly get deleted while they were still referenced
+ * inside the attribute state stack.
+ */
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+ ctx->Texture.Unit[u].Current1D->RefCount--;
+ ctx->Texture.Unit[u].Current2D->RefCount--;
+ ctx->Texture.Unit[u].Current3D->RefCount--;
+ ctx->Texture.Unit[u].CurrentCubeMap->RefCount--;
+ ctx->Texture.Unit[u].CurrentRect->RefCount--;
+ }
+}
+
+