Remove ctx->Point._Size and ctx->Line._Width.
[mesa.git] / src / mesa / main / state.c
index 1ced2a081e5ff794456d7b5d6a2882100dc355d1..444f227760182c102d6e9d40ab8e46457dbac701 100644 (file)
 #include "accum.h"
 #include "api_loopback.h"
 #if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
-#include "arbprogram.h"
+#include "shader/arbprogram.h"
 #endif
 #if FEATURE_ATI_fragment_shader
-#include "atifragshader.h"
+#include "shader/atifragshader.h"
 #endif
 #include "attrib.h"
 #include "blend.h"
 #include "lines.h"
 #include "macros.h"
 #include "matrix.h"
-#if FEATURE_ARB_occlusion_query || FEATURE_EXT_timer_query
-#include "occlude.h"
-#endif
 #include "pixel.h"
 #include "points.h"
 #include "polygon.h"
+#if FEATURE_ARB_occlusion_query || FEATURE_EXT_timer_query
+#include "queryobj.h"
+#endif
 #include "rastpos.h"
 #include "state.h"
 #include "stencil.h"
 #include "mtypes.h"
 #include "varray.h"
 #if FEATURE_NV_vertex_program
-#include "nvprogram.h"
+#include "shader/nvprogram.h"
 #endif
 #if FEATURE_NV_fragment_program
-#include "nvprogram.h"
-#include "program.h"
+#include "shader/nvprogram.h"
+#include "shader/program.h"
 #include "texenvprogram.h"
 #endif
 #if FEATURE_ARB_shader_objects
-#include "shaderobjects.h"
+#include "shaders.h"
 #endif
 #include "debug.h"
-#include "dispatch.h"
+#include "glapi/dispatch.h"
 
 
 
@@ -376,6 +376,32 @@ _mesa_init_exec_table(struct _glapi_table *exec)
    SET_StencilFuncSeparate(exec, _mesa_StencilFuncSeparate);
    SET_StencilMaskSeparate(exec, _mesa_StencilMaskSeparate);
    SET_StencilOpSeparate(exec, _mesa_StencilOpSeparate);
+#if FEATURE_ARB_shader_objects
+   SET_AttachShader(exec, _mesa_AttachShader);
+   SET_CreateProgram(exec, _mesa_CreateProgram);
+   SET_CreateShader(exec, _mesa_CreateShader);
+   SET_DeleteProgram(exec, _mesa_DeleteProgram);
+   SET_DeleteShader(exec, _mesa_DeleteShader);
+   SET_DetachShader(exec, _mesa_DetachShader);
+   SET_GetAttachedShaders(exec, _mesa_GetAttachedShaders);
+   SET_GetProgramiv(exec, _mesa_GetProgramiv);
+   SET_GetProgramInfoLog(exec, _mesa_GetProgramInfoLog);
+   SET_GetShaderiv(exec, _mesa_GetShaderiv);
+   SET_GetShaderInfoLog(exec, _mesa_GetShaderInfoLog);
+   SET_IsProgram(exec, _mesa_IsProgram);
+   SET_IsShader(exec, _mesa_IsShader);
+#endif
+
+   /* OpenGL 2.1 */
+#if FEATURE_ARB_shader_objects
+   SET_UniformMatrix2x3fv(exec, _mesa_UniformMatrix2x3fv);
+   SET_UniformMatrix3x2fv(exec, _mesa_UniformMatrix3x2fv);
+   SET_UniformMatrix2x4fv(exec, _mesa_UniformMatrix2x4fv);
+   SET_UniformMatrix4x2fv(exec, _mesa_UniformMatrix4x2fv);
+   SET_UniformMatrix3x4fv(exec, _mesa_UniformMatrix3x4fv);
+   SET_UniformMatrix4x3fv(exec, _mesa_UniformMatrix4x3fv);
+#endif
+
 
    /* 2. GL_EXT_blend_color */
 #if 0
@@ -786,6 +812,11 @@ _mesa_init_exec_table(struct _glapi_table *exec)
    SET_ProgramEnvParameters4fvEXT(exec, _mesa_ProgramEnvParameters4fvEXT);
    SET_ProgramLocalParameters4fvEXT(exec, _mesa_ProgramLocalParameters4fvEXT);
 #endif
+
+   /* GL_MESA_texture_array / GL_EXT_texture_array */
+#if FEATURE_EXT_framebuffer_object
+   SET_FramebufferTextureLayerEXT(exec, _mesa_FramebufferTextureLayerEXT);
+#endif
 }
 
 
@@ -795,16 +826,6 @@ _mesa_init_exec_table(struct _glapi_table *exec)
 /*@{*/
 
 
-static void
-update_separate_specular( GLcontext *ctx )
-{
-   if (NEED_SECONDARY_COLOR(ctx))
-      ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR;
-   else
-      ctx->_TriangleCaps &= ~DD_SEPARATE_SPECULAR;
-}
-
-
 /**
  * Update state dependent on vertex arrays.
  */
@@ -816,11 +837,7 @@ update_arrays( GLcontext *ctx )
    /* find min of _MaxElement values for all enabled arrays */
 
    /* 0 */
-   if (ctx->ShaderObjects._VertexShaderPresent
-       && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) {
-      min = ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0]._MaxElement;
-   }
-   else if (ctx->VertexProgram._Enabled
+   if (ctx->VertexProgram._Current
        && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) {
       min = ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS]._MaxElement;
    }
@@ -887,8 +904,8 @@ update_arrays( GLcontext *ctx )
 
    /* 7 */
    if (ctx->VertexProgram._Enabled
-       && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_SEVEN].Enabled) {
-      min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_SEVEN]._MaxElement);
+       && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) {
+      min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]._MaxElement);
    }
 
    /* 8..15 */
@@ -904,7 +921,7 @@ update_arrays( GLcontext *ctx )
    }
 
    /* 16..31 */
-   if (ctx->ShaderObjects._VertexShaderPresent) {
+   if (ctx->VertexProgram._Current) {
       for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) {
          if (ctx->Array.ArrayObj->VertexAttrib[i].Enabled) {
             min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[i]._MaxElement);
@@ -927,29 +944,75 @@ update_arrays( GLcontext *ctx )
 static void
 update_program(GLcontext *ctx)
 {
-   /* For now, just set the _Enabled (really enabled) flags.
-    * In the future we may have to check other state to be sure we really
-    * have a runable program or shader.
-    */
+   const struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
+
+   /* These _Enabled flags indicate if the program is enabled AND valid. */
    ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled
       && ctx->VertexProgram.Current->Base.Instructions;
    ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled
       && ctx->FragmentProgram.Current->Base.Instructions;
    ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled
       && ctx->ATIFragmentShader.Current->Instructions;
-      
-   ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
-   ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled;
 
-   if (ctx->_MaintainTexEnvProgram && !ctx->FragmentProgram._Enabled) {
-#if 0
-      if (!ctx->_TexEnvProgram)
-        ctx->_TexEnvProgram = (struct gl_fragment_program *)
-           ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
-      ctx->FragmentProgram._Current = ctx->_TexEnvProgram;
-#endif
+   /*
+    * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current
+    * pointers to the programs that should be enabled/used.
+    *
+    * These programs may come from several sources.  The priority is as
+    * follows:
+    *   1. OpenGL 2.0/ARB vertex/fragment shaders
+    *   2. ARB/NV vertex/fragment programs
+    *   3. Programs derived from fixed-function state.
+    */
+
+   ctx->FragmentProgram._Current = NULL;
+
+   if (shProg && shProg->LinkStatus) {
+      /* Use shader programs */
+      /* XXX this isn't quite right, since we may have either a vertex
+       * _or_ fragment shader (not always both).
+       */
+      ctx->VertexProgram._Current = shProg->VertexProgram;
+      ctx->FragmentProgram._Current = shProg->FragmentProgram;
+   }
+   else {
+      if (ctx->VertexProgram._Enabled) {
+         /* use user-defined vertex program */
+         ctx->VertexProgram._Current = ctx->VertexProgram.Current;
+      }
+      else if (ctx->VertexProgram._MaintainTnlProgram) {
+         /* Use vertex program generated from fixed-function state.
+          * The _Current pointer will get set in
+          * _tnl_UpdateFixedFunctionProgram() later if appropriate.
+          */
+         ctx->VertexProgram._Current = NULL;
+      }
+      else {
+         /* no vertex program */
+         ctx->VertexProgram._Current = NULL;
+      }
+
+      if (ctx->FragmentProgram._Enabled) {
+         /* use user-defined vertex program */
+         ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
+      }
+      else if (ctx->FragmentProgram._MaintainTexEnvProgram) {
+         /* Use fragment program generated from fixed-function state.
+          * The _Current pointer will get set in _mesa_UpdateTexEnvProgram()
+          * later if appropriate.
+          */
+         ctx->FragmentProgram._Current = NULL;
+      }
+      else {
+         /* no fragment program */
+         ctx->FragmentProgram._Current = NULL;
+      }
+   }
 
-      if (ctx->_UseTexEnvProgram)
+   ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled;
+   if (ctx->FragmentProgram._MaintainTexEnvProgram &&
+       !ctx->FragmentProgram._Enabled) {
+      if (ctx->FragmentProgram._UseTexEnvProgram)
         ctx->FragmentProgram._Active = GL_TRUE;
    }
 }
@@ -983,23 +1046,94 @@ update_color(GLcontext *ctx)
    /* This is needed to support 1.1's RGB logic ops AND
     * 1.0's blending logicops.
     */
-   ctx->Color._LogicOpEnabled = (ctx->Color.ColorLogicOpEnabled ||
-                                 (ctx->Color.BlendEnabled &&
-                                  ctx->Color.BlendEquationRGB == GL_LOGIC_OP));
+   ctx->Color._LogicOpEnabled = RGBA_LOGICOP_ENABLED(ctx);
+}
+
+
+
+/**
+ * Update the ctx->_TriangleCaps bitfield.
+ * XXX that bitfield should really go away someday!
+ * This function must be called after other update_*() functions since
+ * there are dependencies on some other derived values.
+ */
+static void
+update_tricaps(GLcontext *ctx, GLbitfield new_state)
+{
+   ctx->_TriangleCaps = 0;
+
+   /*
+    * Points
+    */
+   if (1/*new_state & _NEW_POINT*/) {
+      if (ctx->Point.SmoothFlag)
+         ctx->_TriangleCaps |= DD_POINT_SMOOTH;
+      if (ctx->Point.Size != 1.0F)
+         ctx->_TriangleCaps |= DD_POINT_SIZE;
+      if (ctx->Point._Attenuated)
+         ctx->_TriangleCaps |= DD_POINT_ATTEN;
+   }
+
+   /*
+    * Lines
+    */
+   if (1/*new_state & _NEW_LINE*/) {
+      if (ctx->Line.SmoothFlag)
+         ctx->_TriangleCaps |= DD_LINE_SMOOTH;
+      if (ctx->Line.StippleFlag)
+         ctx->_TriangleCaps |= DD_LINE_STIPPLE;
+      if (ctx->Line.Width != 1.0)
+         ctx->_TriangleCaps |= DD_LINE_WIDTH;
+   }
+
+   /*
+    * Polygons
+    */
+   if (1/*new_state & _NEW_POLYGON*/) {
+      if (ctx->Polygon.SmoothFlag)
+         ctx->_TriangleCaps |= DD_TRI_SMOOTH;
+      if (ctx->Polygon.StippleFlag)
+         ctx->_TriangleCaps |= DD_TRI_STIPPLE;
+      if (ctx->Polygon.FrontMode != GL_FILL
+          || ctx->Polygon.BackMode != GL_FILL)
+         ctx->_TriangleCaps |= DD_TRI_UNFILLED;
+      if (ctx->Polygon.CullFlag
+          && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
+         ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK;
+      if (ctx->Polygon.OffsetPoint ||
+          ctx->Polygon.OffsetLine ||
+          ctx->Polygon.OffsetFill)
+         ctx->_TriangleCaps |= DD_TRI_OFFSET;
+   }
+
+   /*
+    * Lighting and shading
+    */
+   if (ctx->Light.Enabled && ctx->Light.Model.TwoSide)
+      ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE;
+   if (ctx->Light.ShadeModel == GL_FLAT)
+      ctx->_TriangleCaps |= DD_FLATSHADE;
+   if (NEED_SECONDARY_COLOR(ctx))
+      ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR;
+
+   /*
+    * Stencil
+    */
+   if (ctx->Stencil._TestTwoSide)
+      ctx->_TriangleCaps |= DD_TRI_TWOSTENCIL;
 }
 
 
 /**
- * If __GLcontextRec::NewState is non-zero then this function \b must be called
- * before rendering any primitive.  Basically, function pointers and
- * miscellaneous flags are updated to reflect the current state of the state
- * machine.
+ * Compute derived GL state.
+ * If __GLcontextRec::NewState is non-zero then this function \b must
+ * be called before rendering anything.
  *
  * Calls dd_function_table::UpdateState to perform any internal state
  * management necessary.
  * 
  * \sa _mesa_update_modelview_project(), _mesa_update_texture(),
- * _mesa_update_buffer_bounds(), _mesa_update_polygon(),
+ * _mesa_update_buffer_bounds(),
  * _mesa_update_lighting() and _mesa_update_tnl_spaces().
  */
 void
@@ -1025,12 +1159,6 @@ _mesa_update_state_locked( GLcontext *ctx )
    if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
       _mesa_update_draw_buffer_bounds( ctx );
 
-   if (new_state & _NEW_POINT)
-      _mesa_update_point( ctx );
-
-   if (new_state & _NEW_POLYGON)
-      _mesa_update_polygon( ctx );
-
    if (new_state & _NEW_LIGHT)
       _mesa_update_lighting( ctx );
 
@@ -1040,9 +1168,6 @@ _mesa_update_state_locked( GLcontext *ctx )
    if (new_state & _IMAGE_NEW_TRANSFER_STATE)
       _mesa_update_pixel( ctx, new_state );
 
-   if (new_state & _DD_NEW_SEPARATE_SPECULAR)
-      update_separate_specular( ctx );
-
    if (new_state & (_NEW_ARRAY | _NEW_PROGRAM))
       update_arrays( ctx );
 
@@ -1052,7 +1177,11 @@ _mesa_update_state_locked( GLcontext *ctx )
    if (new_state & _NEW_COLOR)
       update_color( ctx );
 
-   if (ctx->_MaintainTexEnvProgram) {
+   if (new_state & (_NEW_POINT | _NEW_LINE | _NEW_POLYGON | _NEW_LIGHT
+                    | _NEW_STENCIL | _DD_NEW_SEPARATE_SPECULAR))
+      update_tricaps( ctx, new_state );
+
+   if (ctx->FragmentProgram._MaintainTexEnvProgram) {
       if (new_state & (_NEW_TEXTURE | _DD_NEW_SEPARATE_SPECULAR | _NEW_FOG))
         _mesa_UpdateTexEnvProgram(ctx);
    }
@@ -1098,3 +1227,5 @@ _mesa_update_state( GLcontext *ctx )
 
 
 /*@}*/
+
+