Support ARB_texture_env_crossbar. Changes the way programs are
[mesa.git] / src / mesa / main / attrib.c
index 8beb0a575b904bedd9519c26eb0bf3a7f583f8b2..da6011c1cef883dee88c1ca7a959d763aa3f55d4 100644 (file)
@@ -1,9 +1,8 @@
-
 /*
  * Mesa 3-D graphics library
- * Version:  5.1
+ * Version:  6.3
  *
- * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -29,6 +28,7 @@
 #include "attrib.h"
 #include "blend.h"
 #include "buffers.h"
+#include "bufferobj.h"
 #include "colormac.h"
 #include "colortab.h"
 #include "context.h"
@@ -190,6 +190,7 @@ _mesa_PushAttrib(GLbitfield mask)
       attr->RescaleNormals = ctx->Transform.RescaleNormals;
       attr->Scissor = ctx->Scissor.Enabled;
       attr->Stencil = ctx->Stencil.Enabled;
+      attr->StencilTwoSide = ctx->Stencil.TestTwoSide;
       attr->MultisampleEnabled = ctx->Multisample.Enabled;
       attr->SampleAlphaToCoverage = ctx->Multisample.SampleAlphaToCoverage;
       attr->SampleAlphaToOne = ctx->Multisample.SampleAlphaToOne;
@@ -518,7 +519,9 @@ pop_enable_group(GLcontext *ctx, const struct gl_enable_attrib *enable)
                    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 */
+   if (ctx->Extensions.EXT_stencil_two_side) {
+      TEST_AND_UPDATE(ctx->Stencil.TestTwoSide, enable->StencilTwoSide, GL_STENCIL_TEST_TWO_SIDE_EXT);
+   }
    TEST_AND_UPDATE(ctx->Multisample.Enabled, enable->MultisampleEnabled,
                    GL_MULTISAMPLE_ARB);
    TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage,
@@ -652,38 +655,38 @@ pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib)
       }
       if (ctx->Extensions.EXT_texture_env_combine ||
           ctx->Extensions.ARB_texture_env_combine) {
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT,
-                       unit->CombineModeRGB);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT,
-                       unit->CombineModeA);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT,
-                       unit->CombineSourceRGB[0]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT,
-                       unit->CombineSourceRGB[1]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT,
-                       unit->CombineSourceRGB[2]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT,
-                       unit->CombineSourceA[0]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT,
-                       unit->CombineSourceA[1]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT,
-                       unit->CombineSourceA[2]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT,
-                       unit->CombineOperandRGB[0]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT,
-                       unit->CombineOperandRGB[1]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT,
-                       unit->CombineOperandRGB[2]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT,
-                       unit->CombineOperandA[0]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT,
-                       unit->CombineOperandA[1]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT,
-                       unit->CombineOperandA[2]);
-         _mesa_TexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT,
-                       1 << unit->CombineScaleShiftRGB);
+         _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->CombineScaleShiftA);
+                       1 << unit->Combine.ScaleShiftA);
       }
 
       /* Restore texture object state */
@@ -830,7 +833,13 @@ _mesa_PopAttrib(void)
                                (GLboolean) (color->ColorMask[1] != 0),
                                (GLboolean) (color->ColorMask[2] != 0),
                                (GLboolean) (color->ColorMask[3] != 0));
-               _mesa_DrawBuffer(color->DrawBuffer);
+#if 0
+               _mesa_DrawBuffersARB(ctx->Const.MaxDrawBuffers,
+                                    color->DrawBuffer);
+#else
+               _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers,
+                                 color->DrawBuffer, NULL);
+#endif
                _mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled);
                _mesa_AlphaFunc(color->AlphaFunc, color->AlphaRef);
                _mesa_set_enable(ctx, GL_BLEND, color->BlendEnabled);
@@ -928,9 +937,8 @@ _mesa_PopAttrib(void)
                /* lighting enable */
                _mesa_set_enable(ctx, GL_LIGHTING, light->Enabled);
                /* per-light state */
-
-              if (ctx->ModelviewMatrixStack.Top->flags & MAT_DIRTY_INVERSE) 
-                 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
+               if (ctx->ModelviewMatrixStack.Top->flags & MAT_DIRTY_INVERSE) 
+                  _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
               
                for (i = 0; i < MAX_LIGHTS; i++) {
                   GLenum lgt = (GLenum) (GL_LIGHT0 + i);
@@ -989,6 +997,8 @@ _mesa_PopAttrib(void)
             break;
          case GL_PIXEL_MODE_BIT:
             MEMCPY( &ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib) );
+            /* XXX what other pixel state needs to be set by function calls? */
+            _mesa_ReadBuffer(ctx->Pixel.ReadBuffer);
            ctx->NewState |= _NEW_PIXEL;
             break;
          case GL_POINT_BIT:
@@ -1017,6 +1027,8 @@ _mesa_PopAttrib(void)
                   _mesa_set_enable(ctx, GL_POINT_SPRITE_NV,point->PointSprite);
                   _mesa_PointParameteriNV(GL_POINT_SPRITE_R_MODE_NV,
                                           ctx->Point.SpriteRMode);
+                  _mesa_PointParameterfEXT(GL_POINT_SPRITE_COORD_ORIGIN,
+                                           (GLfloat)ctx->Point.SpriteOrigin);
                }
             }
             break;
@@ -1058,17 +1070,26 @@ _mesa_PopAttrib(void)
             break;
          case GL_STENCIL_BUFFER_BIT:
             {
-               const GLint face = 0; /* XXX stencil two side */
+               GLint face;
                const struct gl_stencil_attrib *stencil;
                stencil = (const struct gl_stencil_attrib *) attr->data;
                _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled);
                _mesa_ClearStencil(stencil->Clear);
-               _mesa_StencilFunc(stencil->Function[face], stencil->Ref[face],
-                                 stencil->ValueMask[face]);
-               _mesa_StencilMask(stencil->WriteMask[face]);
-               _mesa_StencilOp(stencil->FailFunc[face],
-                               stencil->ZFailFunc[face],
-                               stencil->ZPassFunc[face]);
+               face = stencil->ActiveFace;
+               if (ctx->Extensions.EXT_stencil_two_side) {
+                  _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT, stencil->TestTwoSide);
+                  face ^= 1;
+               }
+               do {
+                  _mesa_ActiveStencilFaceEXT(face);
+                  _mesa_StencilFunc(stencil->Function[face], stencil->Ref[face],
+                                    stencil->ValueMask[face]);
+                  _mesa_StencilMask(stencil->WriteMask[face]);
+                  _mesa_StencilOp(stencil->FailFunc[face],
+                                  stencil->ZFailFunc[face],
+                                  stencil->ZPassFunc[face]);
+                  face ^= 1;
+               } while (face != (stencil->ActiveFace ^ 1));
             }
             break;
          case GL_TRANSFORM_BIT:
@@ -1077,7 +1098,6 @@ _mesa_PopAttrib(void)
                const struct gl_transform_attrib *xform;
                xform = (const struct gl_transform_attrib *) attr->data;
                _mesa_MatrixMode(xform->MatrixMode);
-
                if (ctx->ProjectionMatrixStack.Top->flags & MAT_DIRTY)
                   _math_matrix_analyse( ctx->ProjectionMatrixStack.Top );
 
@@ -1143,6 +1163,31 @@ _mesa_PopAttrib(void)
 }
 
 
+/**
+ * Helper for incrementing/decrementing vertex buffer object reference
+ * counts when pushing/popping the GL_CLIENT_VERTEX_ARRAY_BIT attribute group.
+ */
+static void
+adjust_buffer_object_ref_counts(struct gl_array_attrib *array, GLint step)
+{
+   GLuint i;
+   array->Vertex.BufferObj->RefCount += step;
+   array->Normal.BufferObj->RefCount += step;
+   array->Color.BufferObj->RefCount += step;
+   array->SecondaryColor.BufferObj->RefCount += step;
+   array->FogCoord.BufferObj->RefCount += step;
+   array->Index.BufferObj->RefCount += step;
+   array->EdgeFlag.BufferObj->RefCount += step;
+   for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++)
+      array->TexCoord[i].BufferObj->RefCount += step;
+   for (i = 0; i < VERT_ATTRIB_MAX; i++)
+      array->VertexAttrib[i].BufferObj->RefCount += step;
+
+   array->ArrayBufferObj->RefCount += step;
+   array->ElementArrayBufferObj->RefCount += step;
+}
+
+
 #define GL_CLIENT_PACK_BIT (1<<20)
 #define GL_CLIENT_UNPACK_BIT (1<<21)
 
@@ -1167,6 +1212,10 @@ _mesa_PushClientAttrib(GLbitfield mask)
 
    if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
       struct gl_pixelstore_attrib *attr;
+#if FEATURE_EXT_pixel_buffer_object
+      ctx->Pack.BufferObj->RefCount++;
+      ctx->Unpack.BufferObj->RefCount++;
+#endif
       /* packing attribs */
       attr = MALLOC_STRUCT( gl_pixelstore_attrib );
       MEMCPY( attr, &ctx->Pack, sizeof(struct gl_pixelstore_attrib) );
@@ -1190,6 +1239,8 @@ _mesa_PushClientAttrib(GLbitfield mask)
       newnode->data = attr;
       newnode->next = head;
       head = newnode;
+      /* bump reference counts on buffer objects */
+      adjust_buffer_object_ref_counts(&ctx->Array, 1);
    }
 
    ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head;
@@ -1218,18 +1269,34 @@ _mesa_PopClientAttrib(void)
    while (attr) {
       switch (attr->kind) {
          case GL_CLIENT_PACK_BIT:
+#if FEATURE_EXT_pixel_buffer_object
+            ctx->Pack.BufferObj->RefCount--;
+            if (ctx->Pack.BufferObj->RefCount <= 0) {
+               _mesa_remove_buffer_object( ctx, ctx->Pack.BufferObj );
+               (*ctx->Driver.DeleteBuffer)( ctx, ctx->Pack.BufferObj );
+            }
+#endif
             MEMCPY( &ctx->Pack, attr->data,
                     sizeof(struct gl_pixelstore_attrib) );
            ctx->NewState |= _NEW_PACKUNPACK;
             break;
          case GL_CLIENT_UNPACK_BIT:
+#if FEATURE_EXT_pixel_buffer_object
+            ctx->Unpack.BufferObj->RefCount--;
+            if (ctx->Unpack.BufferObj->RefCount <= 0) {
+               _mesa_remove_buffer_object( ctx, ctx->Unpack.BufferObj );
+               (*ctx->Driver.DeleteBuffer)( ctx, ctx->Unpack.BufferObj );
+            }
+#endif
             MEMCPY( &ctx->Unpack, attr->data,
                     sizeof(struct gl_pixelstore_attrib) );
            ctx->NewState |= _NEW_PACKUNPACK;
             break;
          case GL_CLIENT_VERTEX_ARRAY_BIT:
+            adjust_buffer_object_ref_counts(&ctx->Array, -1);
             MEMCPY( &ctx->Array, attr->data,
                    sizeof(struct gl_array_attrib) );
+            /* decrement reference counts on buffer objects */
            ctx->NewState |= _NEW_ARRAY;
             break;
          default: