OSDN Git Service

Lots of assorted changes for new GLSL compiler backend.
authorBrian <brian@yutani.localnet.net>
Fri, 15 Dec 2006 17:07:26 +0000 (10:07 -0700)
committerBrian <brian@yutani.localnet.net>
Fri, 15 Dec 2006 17:07:26 +0000 (10:07 -0700)
New datatypes, constants, variables.

src/mesa/main/config.h
src/mesa/main/context.c
src/mesa/main/extensions.c
src/mesa/main/get.c
src/mesa/main/get_gen.py
src/mesa/main/mtypes.h
src/mesa/main/state.c
src/mesa/main/texenvprogram.c
src/mesa/main/texstate.c

index 13c6281..d779860 100644 (file)
 #define MAX_PROGRAM_MATRICES 8
 #define MAX_PROGRAM_MATRIX_STACK_DEPTH 4
 #define MAX_PROGRAM_CALL_DEPTH 8
-/*@}*/
-
-/** For GL_ARB_fragment_shader */
-/*@{*/
-#define MAX_FRAGMENT_UNIFORM_COMPONENTS 64
+#define MAX_PROGRAM_TEMPS 128
+#define MAX_UNIFORMS 128
+#define MAX_VARYING 8
 /*@}*/
 
 /** For GL_ARB_vertex_shader */
 /*@{*/
 #define MAX_VERTEX_ATTRIBS 16
-#define MAX_VERTEX_UNIFORM_COMPONENTS 512
-#define MAX_VARYING_FLOATS 32
 #define MAX_VERTEX_TEXTURE_IMAGE_UNITS 0
 #define MAX_COMBINED_TEXTURE_IMAGE_UNITS (MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS)
 /*@}*/
index 7ff45cf..4986b29 100644 (file)
@@ -706,6 +706,8 @@ alloc_shared_state( GLcontext *ctx )
 
 #if FEATURE_ARB_shader_objects
    ss->GL2Objects = _mesa_NewHashTable ();
+   ss->ShaderObjects = _mesa_NewHashTable();
+   ss->ProgramObjects = _mesa_NewHashTable();
 #endif
 
    ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
@@ -782,8 +784,11 @@ alloc_shared_state( GLcontext *ctx )
       _mesa_DeleteHashTable (ss->ArrayObjects);
 
 #if FEATURE_ARB_shader_objects
-   if (ss->GL2Objects)
+   if (ss->GL2Objects) {
       _mesa_DeleteHashTable (ss->GL2Objects);
+      _mesa_DeleteHashTable (ss->ShaderObjects);
+      _mesa_DeleteHashTable (ss->ProgramObjects);
+   }
 #endif
 
 #if FEATURE_EXT_framebuffer_object
@@ -1063,9 +1068,10 @@ _mesa_init_constants( GLcontext *ctx )
    ctx->Const.VertexProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
    ctx->Const.VertexProgram.MaxEnvParams = MAX_NV_VERTEX_PROGRAM_PARAMS;
    ctx->Const.VertexProgram.MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
-   ctx->Const.VertexProgram.MaxUniformComponents = MAX_VERTEX_UNIFORM_COMPONENTS;
+   ctx->Const.VertexProgram.MaxUniformComponents = 4 * MAX_UNIFORMS;
    init_natives(&ctx->Const.VertexProgram);
 #endif
+
 #if FEATURE_ARB_fragment_program
    ctx->Const.FragmentProgram.MaxInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS;
    ctx->Const.FragmentProgram.MaxAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS;
@@ -1077,7 +1083,7 @@ _mesa_init_constants( GLcontext *ctx )
    ctx->Const.FragmentProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
    ctx->Const.FragmentProgram.MaxEnvParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
    ctx->Const.FragmentProgram.MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
-   ctx->Const.FragmentProgram.MaxUniformComponents = MAX_FRAGMENT_UNIFORM_COMPONENTS;
+   ctx->Const.FragmentProgram.MaxUniformComponents = 4 * MAX_UNIFORMS;
    init_natives(&ctx->Const.FragmentProgram);
 #endif
    ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
@@ -1106,7 +1112,7 @@ _mesa_init_constants( GLcontext *ctx )
 
 #if FEATURE_ARB_vertex_shader
    ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
-   ctx->Const.MaxVaryingFloats = MAX_VARYING_FLOATS;
+   ctx->Const.MaxVarying = MAX_VARYING;
 #endif
 
    /* sanity checks */
@@ -1114,6 +1120,11 @@ _mesa_init_constants( GLcontext *ctx )
                                              ctx->Const.MaxTextureCoordUnits));
    ASSERT(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
    ASSERT(ctx->Const.VertexProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
+
+   ASSERT(MAX_NV_FRAGMENT_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS);
+   ASSERT(MAX_NV_VERTEX_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS);
+   ASSERT(MAX_NV_VERTEX_PROGRAM_INPUTS <= VERT_ATTRIB_MAX);
+   ASSERT(MAX_NV_VERTEX_PROGRAM_OUTPUTS <= VERT_RESULT_MAX);
 }
 
 
@@ -1351,12 +1362,14 @@ _mesa_initialize_context( GLcontext *ctx,
    ctx->TnlModule.SwapCount = 0;
 #endif
 
-   ctx->_MaintainTexEnvProgram = (_mesa_getenv("MESA_TEX_PROG") != NULL);
-   ctx->_UseTexEnvProgram = ctx->_MaintainTexEnvProgram;
-
-   ctx->_MaintainTnlProgram = (_mesa_getenv("MESA_TNL_PROG") != NULL);
-   if (ctx->_MaintainTnlProgram)
-      ctx->_MaintainTexEnvProgram = 1; /* this is required... */
+   ctx->VertexProgram._MaintainTnlProgram
+      = (_mesa_getenv("MESA_TNL_PROG") != NULL);
+   if (ctx->VertexProgram._MaintainTnlProgram)
+      /* this is required... */
+      ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
+   else
+      ctx->FragmentProgram._MaintainTexEnvProgram
+         = (_mesa_getenv("MESA_TEX_PROG") != NULL);
 
    ctx->FirstTimeCurrent = GL_TRUE;
 
@@ -1678,6 +1691,10 @@ void
 _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
                     GLframebuffer *readBuffer )
 {
+#if 0
+   GET_CURRENT_CONTEXT(oldCtx);
+#endif
+
    if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(newCtx, "_mesa_make_current()\n");
 
@@ -1698,6 +1715,30 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
       }
    }
 
+#if 0 /** XXX enable this someday */
+   if (oldCtx && oldCtx != newCtx) {
+      /* unbind old context's draw/read buffers */
+      if (oldCtx->DrawBuffer && oldCtx->DrawBuffer->Name == 0) {
+         oldCtx->DrawBuffer->RefCount--;
+         oldCtx->DrawBuffer = NULL;
+      }
+      if (oldCtx->ReadBuffer && oldCtx->ReadBuffer->Name == 0) {
+         oldCtx->ReadBuffer->RefCount--;
+         oldCtx->ReadBuffer = NULL;
+      }
+      if (oldCtx->WinSysDrawBuffer) {
+         ASSERT(oldCtx->WinSysDrawBuffer->Name == 0);
+         oldCtx->WinSysDrawBuffer->RefCount--;
+         oldCtx->WinSysDrawBuffer = NULL;
+      }
+      if (oldCtx->WinSysReadBuffer) {
+         ASSERT(oldCtx->WinSysReadBuffer->Name == 0);
+         oldCtx->WinSysReadBuffer->RefCount--;
+         oldCtx->WinSysReadBuffer = NULL;
+      }
+   }
+#endif
+
    /* We used to call _glapi_check_multithread() here.  Now do it in drivers */
    _glapi_set_context((void *) newCtx);
    ASSERT(_mesa_get_current_context() == newCtx);
index 135323f..7845ea0 100644 (file)
@@ -409,7 +409,9 @@ _mesa_enable_2_1_extensions(GLcontext *ctx)
 #if FEATURE_EXT_texture_sRGB
    ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
 #endif
-   /* plus: shading language extensions, non-square uniform matrices */
+#ifdef FEATURE_ARB_shading_language_120
+   ctx->Extensions.ARB_shading_language_120 = GL_TRUE;
+#endif
 }
 
 
index 858c822..335443e 100644 (file)
@@ -1878,7 +1878,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
          break;
       case GL_MAX_VARYING_FLOATS_ARB:
          CHECK_EXT1(ARB_vertex_shader, "GetBooleanv");
-         params[0] = INT_TO_BOOLEAN(ctx->Const.MaxVaryingFloats);
+         params[0] = INT_TO_BOOLEAN(ctx->Const.MaxVarying * 4);
          break;
       case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB:
          CHECK_EXT1(ARB_vertex_shader, "GetBooleanv");
@@ -3705,7 +3705,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
          break;
       case GL_MAX_VARYING_FLOATS_ARB:
          CHECK_EXT1(ARB_vertex_shader, "GetFloatv");
-         params[0] = (GLfloat)(ctx->Const.MaxVaryingFloats);
+         params[0] = (GLfloat)(ctx->Const.MaxVarying * 4);
          break;
       case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB:
          CHECK_EXT1(ARB_vertex_shader, "GetFloatv");
@@ -5532,7 +5532,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
          break;
       case GL_MAX_VARYING_FLOATS_ARB:
          CHECK_EXT1(ARB_vertex_shader, "GetIntegerv");
-         params[0] = ctx->Const.MaxVaryingFloats;
+         params[0] = ctx->Const.MaxVarying * 4;
          break;
       case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB:
          CHECK_EXT1(ARB_vertex_shader, "GetIntegerv");
index 0f2ca00..5a9ca07 100644 (file)
@@ -989,7 +989,7 @@ StateVars = [
          ["ctx->Const.VertexProgram.MaxUniformComponents"], "",
          ["ARB_vertex_shader"] ),
        ( "GL_MAX_VARYING_FLOATS_ARB", GLint,
-         ["ctx->Const.MaxVaryingFloats"], "", ["ARB_vertex_shader"] ),
+         ["ctx->Const.MaxVarying * 4"], "", ["ARB_vertex_shader"] ),
        ( "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB", GLint,
          ["ctx->Const.MaxVertexTextureImageUnits"], "", ["ARB_vertex_shader"] ),
        ( "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB", GLint,
index 0ed73be..5ed95cc 100644 (file)
@@ -213,22 +213,6 @@ enum
 #define VERT_BIT_GENERIC(g)  (1 << (VERT_ATTRIB_GENERIC0 + (g)))
 /*@}*/
 
-/**
- * GLSL allows shader writers to allocate vertex result attributes (varyings) in
- * single float component granularity. This is in contrast to vertex / fragment
- * programs, where result attributes (actually texcoords) were allocated
- * in 4-component vectors of floats granularity.
- * For performance reasons, it would be optimal to stick with this scheme on a scalar
- * processor. Varyings will likely be allocated as 3-component vectors, so statistically
- * we win 2 floats.
- * The constant VARYINGS_PER_VECTOR tells us how much of float components we pack into
- * one result vector. For scalar processor it would be 1, for vector processor - 4.
- * 
- * NOTE: Currently we pack varyings into vertex attributes.
- */
-#define VARYINGS_PER_VECTOR 2
-#define VARYING_EMIT_STYLE  EMIT_2F
-#define MAX_VARYING_VECTORS ((MAX_VARYING_FLOATS + VARYINGS_PER_VECTOR - 1) / VARYINGS_PER_VECTOR)
 
 /**
  * Indexes for vertex program result attributes
@@ -250,7 +234,8 @@ enum
 #define VERT_RESULT_BFC0 13
 #define VERT_RESULT_BFC1 14
 #define VERT_RESULT_EDGE 15
-#define VERT_RESULT_MAX  16
+#define VERT_RESULT_VAR0 16  /**< shader varying */
+#define VERT_RESULT_MAX  (VERT_RESULT_VAR0 + MAX_VARYING)
 /*@}*/
 
 
@@ -271,7 +256,8 @@ enum
    FRAG_ATTRIB_TEX5 = 9,
    FRAG_ATTRIB_TEX6 = 10,
    FRAG_ATTRIB_TEX7 = 11,
-   FRAG_ATTRIB_MAX = 12
+   FRAG_ATTRIB_VAR0 = 12,  /**< shader varying */
+   FRAG_ATTRIB_MAX = (FRAG_ATTRIB_VAR0 + MAX_VARYING)
 };
 
 /**
@@ -305,12 +291,13 @@ enum
 /**
  * Fragment program results
  */
-/*@{*/
-#define FRAG_RESULT_COLR  0
-#define FRAG_RESULT_COLH  1
-#define FRAG_RESULT_DEPR  2
-#define FRAG_RESULT_MAX   3
-/*@}*/
+enum
+{
+   FRAG_RESULT_COLR = 0,
+   FRAG_RESULT_COLH = 1,
+   FRAG_RESULT_DEPR = 2,
+   FRAG_RESULT_MAX = 3
+};
 
 
 /**
@@ -1811,22 +1798,30 @@ struct gl_evaluators
 
 /**
  * Names of the various vertex/fragment program register files, etc.
+ *
  * NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c)
  * All values should fit in a 4-bit field.
+ *
+ * NOTE: PROGRAM_ENV_PARAM, PROGRAM_STATE_VAR, PROGRAM_NAMED_PARAM,
+ * PROGRAM_CONSTANT, and PROGRAM_UNIFORM can all be considered to
+ * be "uniform" variables since they can only be set outside glBegin/End.
+ * They're also all stored in the same Parameters array.
  */
 enum register_file
 {
-   PROGRAM_TEMPORARY = 0,
-   PROGRAM_LOCAL_PARAM = 1,
-   PROGRAM_ENV_PARAM = 2,
-   PROGRAM_STATE_VAR = 3,
-   PROGRAM_INPUT = 4,
-   PROGRAM_OUTPUT = 5,
-   PROGRAM_NAMED_PARAM = 6,
-   PROGRAM_CONSTANT = 7,
-   PROGRAM_WRITE_ONLY = 8,
-   PROGRAM_ADDRESS = 9,
-   PROGRAM_UNDEFINED = 10,  /* invalid value */
+   PROGRAM_TEMPORARY = 0,   /**< machine->Temporary[] */
+   PROGRAM_LOCAL_PARAM = 1, /**< gl_program->LocalParams[] */
+   PROGRAM_ENV_PARAM = 2,   /**< gl_program->Parameters[] */
+   PROGRAM_STATE_VAR = 3,   /**< gl_program->Parameters[] */
+   PROGRAM_INPUT = 4,       /**< machine->Inputs[] */
+   PROGRAM_OUTPUT = 5,      /**< machine->Outputs[] */
+   PROGRAM_NAMED_PARAM = 6, /**< gl_program->Parameters[] */
+   PROGRAM_CONSTANT = 7,    /**< gl_program->Parameters[] */
+   PROGRAM_UNIFORM = 8,     /**< gl_program->Parameters[] */
+   PROGRAM_VARYING = 9,     /**< machine->Inputs[]/Outputs[] */
+   PROGRAM_WRITE_ONLY = 10, /**< A dummy, write-only register */
+   PROGRAM_ADDRESS = 11,    /**< machine->AddressReg */
+   PROGRAM_UNDEFINED = 12,  /**< Invalid value */
    PROGRAM_FILE_MAX
 };
 
@@ -1858,6 +1853,9 @@ struct gl_program
    /** Numbered local parameters */
    GLfloat LocalParams[MAX_PROGRAM_LOCAL_PARAMS][4];
 
+   /** Vertex/fragment shader varying vars */
+   struct gl_program_parameter_list *Varying;
+
    /** Logical counts */
    /*@{*/
    GLuint NumInstructions;
@@ -1923,9 +1921,9 @@ struct gl_vertex_program_state
    GLboolean PointSizeEnabled;      /**< GL_VERTEX_PROGRAM_POINT_SIZE_ARB/NV */
    GLboolean TwoSideEnabled;        /**< GL_VERTEX_PROGRAM_TWO_SIDE_ARB/NV */
    struct gl_vertex_program *Current;  /**< ptr to currently bound program */
-   const struct gl_vertex_program *_Current;    /**< ptr to currently bound
-                                                 program, including internal
-                                                 (t_vp_build.c) programs */
+
+   /** Currently enabled and valid program (including internal programs) */
+   struct gl_vertex_program *_Current;
 
    GLfloat Parameters[MAX_NV_VERTEX_PROGRAM_PARAMS][4]; /**< Env params */
 
@@ -1933,6 +1931,12 @@ struct gl_vertex_program_state
    GLenum TrackMatrix[MAX_NV_VERTEX_PROGRAM_PARAMS / 4];
    GLenum TrackMatrixTransform[MAX_NV_VERTEX_PROGRAM_PARAMS / 4];
 
+   /** Should fixed-function T&L be implemented with a vertex prog? */
+   GLboolean _MaintainTnlProgram;
+
+   /** Program to emulate fixed-function T&L (see above) */
+   struct gl_vertex_program *_TnlProgram;
+
 #if FEATURE_MESA_program_debug
    GLprogramcallbackMESA Callback;
    GLvoid *CallbackData;
@@ -1949,12 +1953,19 @@ struct gl_fragment_program_state
 {
    GLboolean Enabled;     /**< User-set fragment program enable flag */
    GLboolean _Enabled;    /**< Fragment program enabled and valid? */
-   GLboolean _Active;     /**< Is a user program or internal program active? */
    struct gl_fragment_program *Current;  /**< User-bound program */
-   const struct gl_fragment_program *_Current; /**< currently active program 
-                                              (including internal programs) */
+
+   /** Currently enabled and valid program (including internal programs) */
+   struct gl_fragment_program *_Current;
+
    GLfloat Parameters[MAX_NV_FRAGMENT_PROGRAM_PARAMS][4]; /**< Env params */
 
+   /** Should fixed-function texturing be implemented with a fragment prog? */
+   GLboolean _MaintainTexEnvProgram;
+
+   /** Program to emulate fixed-function texture env/combine (see above) */
+   struct gl_fragment_program *_TexEnvProgram;
+
 #if FEATURE_MESA_program_debug
    GLprogramcallbackMESA Callback;
    GLvoid *CallbackData;
@@ -2030,6 +2041,41 @@ struct gl_query_state
 };
 
 
+
+/**
+ * A GLSL shader object
+ * A collection of one or more gl_programs...
+ */
+struct gl_shader
+{
+   GLenum Type;  /**< GL_FRAGMENT_SHADER || GL_VERTEX_SHADER */
+   GLuint Name;  /**< AKA the handle */
+   GLchar *Source;  /**< Source code string */
+   GLboolean CompileStatus;
+   GLuint NumPrograms;  /**< size of Programs[] array */
+   struct gl_program **Programs;  /**< Post-compile assembly code */
+};
+
+
+/**
+ * This corresponds to a GLSL "program" and is basically a linked collection
+ * of "shaders" (which are Mesa gl_programs).
+ * Yes, the terminology is a bit confusing.
+ */
+struct gl_linked_program
+{
+   GLenum Type;
+   GLuint Name;  /**< aka handle or ID */
+   GLuint NumShaders;          /**< total number of shaders in this program */
+   struct gl_program **Shaders; /**< List of the shaders */
+   struct gl_vertex_program *VertexProgram;     /**< Linked vertex program */
+   struct gl_fragment_program *FragmentProgram; /**< Linked fragment prog */
+   GLboolean LinkStatus;   /**< GL_LINK_STATUS */
+   struct gl_program_parameter_list *Uniforms; /**< Plus constants, etc */
+   struct gl_program_parameter_list *Varying;
+};   
+
+
 /**
  * Context state for vertex/fragment shaders.
  */
@@ -2038,6 +2084,7 @@ struct gl_shader_objects_state
    struct gl2_program_intf **CurrentProgram;
    GLboolean _VertexShaderPresent;
    GLboolean _FragmentShaderPresent;
+   struct gl_linked_program *Linked; /* XXX temporary here */
 };
 
 
@@ -2099,6 +2146,8 @@ struct gl_shared_state
 
 #if FEATURE_ARB_shader_objects
    struct _mesa_HashTable *GL2Objects;
+   struct _mesa_HashTable *ShaderObjects;
+   struct _mesa_HashTable *ProgramObjects;
 #endif
 
 #if FEATURE_EXT_framebuffer_object
@@ -2377,7 +2426,7 @@ struct gl_constants
    GLuint MaxRenderbufferSize;
    /* GL_ARB_vertex_shader */
    GLuint MaxVertexTextureImageUnits;
-   GLuint MaxVaryingFloats;
+   GLuint MaxVarying;
 };
 
 
@@ -2915,13 +2964,6 @@ struct __GLcontextRec
    struct gl_fragment_program_state FragmentProgram;  /**< GL_ARB/NV_vertex_program */
    struct gl_ati_fragment_shader_state ATIFragmentShader;  /**< GL_ATI_fragment_shader */
 
-   struct gl_fragment_program *_TexEnvProgram;     /**< Texture state as fragment program */
-   struct gl_vertex_program *_TnlProgram;          /**< Fixed func TNL state as vertex program */
-
-   GLboolean _MaintainTnlProgram;
-   GLboolean _MaintainTexEnvProgram;
-   GLboolean _UseTexEnvProgram;
-
    struct gl_query_state Query;  /**< GL_ARB_occlusion_query */
 
    struct gl_shader_objects_state ShaderObjects;       /* GL_ARB_shader_objects */
index e62fbe4..e121f59 100644 (file)
@@ -842,11 +842,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;
    }
@@ -930,7 +926,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);
@@ -953,30 +949,67 @@ 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_linked_program *linked = ctx->ShaderObjects.Linked;
+
+
+   /* 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 (linked && linked->LinkStatus) {
+      /* Use shader programs */
+      ctx->VertexProgram._Current = linked->VertexProgram;
+      ctx->FragmentProgram._Current = linked->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->_UseTexEnvProgram)
-        ctx->FragmentProgram._Active = GL_TRUE;
+      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;
+      }
    }
 }
 
@@ -1013,11 +1046,11 @@ update_color(GLcontext *ctx)
 }
 
 
+
 /**
- * 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.
@@ -1076,7 +1109,7 @@ _mesa_update_state_locked( GLcontext *ctx )
    if (new_state & _NEW_COLOR)
       update_color( ctx );
 
-   if (ctx->_MaintainTexEnvProgram) {
+   if (ctx->FragmentProgram._MaintainTexEnvProgram) {
       if (new_state & (_NEW_TEXTURE | _DD_NEW_SEPARATE_SPECULAR | _NEW_FOG))
         _mesa_UpdateTexEnvProgram(ctx);
    }
@@ -1122,3 +1155,5 @@ _mesa_update_state( GLcontext *ctx )
 
 
 /*@}*/
+
+
index 5329719..d318a43 100644 (file)
 #include "glheader.h"
 #include "macros.h"
 #include "enums.h"
+#include "prog_parameter.h"
+#include "prog_instruction.h"
+#include "prog_print.h"
+#include "prog_statevars.h"
 #include "texenvprogram.h"
 
-#include "shader/program.h"
-#include "shader/program_instruction.h"
-
 /**
  * According to Glean's texCombine test, no more than 21 instructions
  * are needed.  Allow a few extra just in case.
@@ -570,12 +571,14 @@ static struct ureg register_const4f( struct texenv_fragment_program *p,
                                     GLfloat s3)
 {
    GLfloat values[4];
-   GLuint idx;
+   GLuint idx, swizzle;
    values[0] = s0;
    values[1] = s1;
    values[2] = s2;
    values[3] = s3;
-   idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4 );
+   idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4,
+                                     &swizzle );
+   ASSERT(swizzle == SWIZZLE_NOOP);
    return make_ureg(PROGRAM_STATE_VAR, idx);
 }
 
@@ -1221,44 +1224,55 @@ static GLuint hash_key( const struct state_key *key )
    return hash;
 }
 
-void _mesa_UpdateTexEnvProgram( GLcontext *ctx )
+
+/**
+ * If _MaintainTexEnvProgram is set we'll generate a fragment program that
+ * implements the current texture env/combine mode.
+ * This function generates that program and puts it into effect.
+ */
+void
+_mesa_UpdateTexEnvProgram( GLcontext *ctx )
 {
    struct state_key key;
    GLuint hash;
    const struct gl_fragment_program *prev = ctx->FragmentProgram._Current;
        
-   if (!ctx->FragmentProgram._Enabled) {
+   ASSERT(ctx->FragmentProgram._MaintainTexEnvProgram);
+
+   /* If a conventional fragment program/shader isn't in effect... */
+   if (!ctx->FragmentProgram._Current) {
       make_state_key(ctx, &key);
       hash = hash_key(&key);
       
-      ctx->FragmentProgram._Current =
-      ctx->_TexEnvProgram =
-        search_cache(&ctx->Texture.env_fp_cache, hash, &key, sizeof(key));
-       
-      if (!ctx->_TexEnvProgram) {
-        if (0) _mesa_printf("Building new texenv proggy for key %x\n", hash);
-               
-        ctx->FragmentProgram._Current = ctx->_TexEnvProgram = 
-           (struct gl_fragment_program *) 
-           ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
-               
-        create_new_program(ctx, &key, ctx->_TexEnvProgram);
+      ctx->FragmentProgram._TexEnvProgram =
+         search_cache(&ctx->Texture.env_fp_cache, hash, &key, sizeof(key));
+
+      if (!ctx->FragmentProgram._TexEnvProgram) {
+         if (0)
+            _mesa_printf("Building new texenv proggy for key %x\n", hash);
+
+         /* create new tex env program */
+         ctx->FragmentProgram._TexEnvProgram = (struct gl_fragment_program *) 
+            ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
+
+         create_new_program(ctx, &key, ctx->FragmentProgram._TexEnvProgram);
 
-        cache_item(&ctx->Texture.env_fp_cache, hash, &key, ctx->_TexEnvProgram);
-      } else {
-        if (0) _mesa_printf("Found existing texenv program for key %x\n", hash);
+         cache_item(&ctx->Texture.env_fp_cache, hash, &key,
+                    ctx->FragmentProgram._TexEnvProgram);
       }
+      else {
+         if (0)
+            _mesa_printf("Found existing texenv program for key %x\n", hash);
+      }
+      ctx->FragmentProgram._Current = ctx->FragmentProgram._TexEnvProgram;
    } 
-   else {
-      ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
-   }
 
    /* Tell the driver about the change.  Could define a new target for
     * this?
     */
    if (ctx->FragmentProgram._Current != prev && ctx->Driver.BindProgram) {
       ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB,
-                             (struct gl_program *) ctx->FragmentProgram._Current);
+                         (struct gl_program *) ctx->FragmentProgram._Current);
    }
 }
 
index bcedcaf..e379933 100644 (file)
@@ -2920,10 +2920,12 @@ update_texture_state( GLcontext *ctx )
 {
    GLuint unit;
 
+#if 0 /** XXX NEW_SLANG */
 #if FEATURE_ARB_fragment_shader
    struct gl2_program_intf **prog = ctx->ShaderObjects.CurrentProgram;
    GLbitfield progteximageusage[MAX_TEXTURE_IMAGE_UNITS];
 #endif
+#endif
 
    ctx->NewState |= _NEW_TEXTURE; /* TODO: only set this if there are 
                                   * actual changes. 
@@ -2934,6 +2936,7 @@ update_texture_state( GLcontext *ctx )
    ctx->Texture._TexMatEnabled = 0;
    ctx->Texture._TexGenEnabled = 0;
 
+#if 00 /* XXX NEW_SLANG */
 #if FEATURE_ARB_fragment_shader
    /*
     * Grab texture image usage state from shader program. It must be
@@ -2944,6 +2947,7 @@ update_texture_state( GLcontext *ctx )
       (**prog).GetTextureImageUsage (prog, progteximageusage);
    }
 #endif /* FEATURE_ARB_fragment_shader */
+#endif
 
    /*
     * Update texture unit state.
@@ -2957,12 +2961,14 @@ update_texture_state( GLcontext *ctx )
       texUnit->_GenFlags = 0;
 
       /* Get the bitmask of texture enables */
+#if 000 /* XXX NEW_SLANG */
 #if FEATURE_ARB_fragment_shader
       if (ctx->ShaderObjects._FragmentShaderPresent) {
          enableBits = progteximageusage[unit];
       }
       else
 #endif
+#endif
       if (ctx->FragmentProgram._Enabled) {
          enableBits = ctx->FragmentProgram.Current->TexturesUsed[unit];
       }
@@ -3085,12 +3091,15 @@ update_texture_state( GLcontext *ctx )
    /* Fragment programs may need texture coordinates but not the
     * corresponding texture images.
     */
+#if 0  /* XXX NEW_SLANG */
    if (ctx->ShaderObjects.CurrentProgram != NULL) {
       ctx->Texture._EnabledCoordUnits |= (1 << ctx->Const.MaxTextureCoordUnits) - 1;
    }
-   else if (ctx->FragmentProgram._Enabled) {
+   else
+#endif
+   if (ctx->FragmentProgram._Enabled) {
       ctx->Texture._EnabledCoordUnits |=
-         (ctx->FragmentProgram.Current->Base.InputsRead >> FRAG_ATTRIB_TEX0);
+         (ctx->FragmentProgram._Current->Base.InputsRead >> FRAG_ATTRIB_TEX0);
    }
 }