Merge commit 'origin/master' into gallium-0.2
authorKeith Whitwell <keith@tungstengraphics.com>
Fri, 10 Oct 2008 14:26:28 +0000 (15:26 +0100)
committerKeith Whitwell <keith@tungstengraphics.com>
Fri, 10 Oct 2008 14:26:28 +0000 (15:26 +0100)
Conflicts:

src/mesa/glapi/descrip.mms
src/mesa/shader/grammar/descrip.mms

1  2 
src/mesa/glapi/glapi.c
src/mesa/main/extensions.c
src/mesa/main/mtypes.h
src/mesa/main/state.c
src/mesa/main/texformat.c
src/mesa/main/teximage.c
src/mesa/shader/arbprogparse.c
src/mesa/shader/program.c
src/mesa/shader/shader_api.c

diff --combined src/mesa/glapi/glapi.c
index 4b23b422233568f5da7e761d17dbf9c0f92c9dd0,c3ebf60719f0d62339802a6510989ded57c69c26..9b5144a88b6a16a61dde005b491872e1a293f382
@@@ -98,7 -98,6 +98,7 @@@ _glapi_set_warning_func( _glapi_warning
  static GLboolean
  warn(void)
  {
 +#if !defined(_WIN32_WCE)
     if ((WarnFlag || getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG"))
         && warning_func) {
        return GL_TRUE;
     else {
        return GL_FALSE;
     }
 +#else
 +   return GL_FALSE;
 +#endif
  }
  
  
@@@ -294,7 -290,31 +294,31 @@@ _glapi_get_context(void
  #endif
  }
  
+ #ifdef USE_X86_ASM
  
+ #if defined( GLX_USE_TLS )
+ extern       GLubyte gl_dispatch_functions_start[];
+ extern       GLubyte gl_dispatch_functions_end[];
+ #else
+ extern const GLubyte gl_dispatch_functions_start[];
+ #endif
+ #endif /* USE_X86_ASM */
+ #if defined(USE_X64_64_ASM) && defined(GLX_USE_TLS)
+ # define DISPATCH_FUNCTION_SIZE  16
+ #elif defined(USE_X86_ASM)
+ # if defined(THREADS) && !defined(GLX_USE_TLS)
+ #  define DISPATCH_FUNCTION_SIZE  32
+ # else
+ #  define DISPATCH_FUNCTION_SIZE  16
+ # endif
+ #endif
+ #if !defined(DISPATCH_FUNCTION_SIZE) && !defined(XFree86Server) && !defined(XGLServer)
+ # define NEED_FUNCTION_POINTER
+ #endif
  
  #if defined(PTHREADS) || defined(GLX_USE_TLS)
  /**
index 8dfbfeb62e43b06a21a228af0d7bcc08a0d0b712,de75325f1520bdb660e4bf2c6557316f9f79c8c4..95bf1165f455eaf4ad37f8677fe13fbdb3a1202c
@@@ -86,7 -86,7 +86,7 @@@ static const struct 
     { OFF, "GL_EXT_blend_logic_op",             F(EXT_blend_logic_op) },
     { OFF, "GL_EXT_blend_minmax",               F(EXT_blend_minmax) },
     { OFF, "GL_EXT_blend_subtract",             F(EXT_blend_subtract) },
 -   { ON,  "GL_EXT_clip_volume_hint",           F(EXT_clip_volume_hint) },
 +   { OFF, "GL_EXT_clip_volume_hint",           F(EXT_clip_volume_hint) },
     { OFF, "GL_EXT_cull_vertex",                F(EXT_cull_vertex) },
     { ON,  "GL_EXT_compiled_vertex_array",      F(EXT_compiled_vertex_array) },
     { OFF, "GL_EXT_convolution",                F(EXT_convolution) },
     { OFF, "GL_SGIS_texture_border_clamp",      F(ARB_texture_border_clamp) },
     { ON,  "GL_SGIS_texture_edge_clamp",        F(SGIS_texture_edge_clamp) },
     { ON,  "GL_SGIS_texture_lod",               F(SGIS_texture_lod) },
-    { OFF, "GL_SGIX_depth_texture",             F(SGIX_depth_texture) },
+    { OFF, "GL_SGIX_depth_texture",             F(ARB_depth_texture) },
     { OFF, "GL_SGIX_shadow",                    F(SGIX_shadow) },
     { OFF, "GL_SGIX_shadow_ambient",            F(SGIX_shadow_ambient) },
     { OFF, "GL_SUN_multi_draw_arrays",          F(EXT_multi_draw_arrays) },
@@@ -292,7 -292,6 +292,6 @@@ _mesa_enable_sw_extensions(GLcontext *c
     ctx->Extensions.SGI_texture_color_table = GL_TRUE;
     ctx->Extensions.SGIS_generate_mipmap = GL_TRUE;
     ctx->Extensions.SGIS_texture_edge_clamp = GL_TRUE;
-    ctx->Extensions.SGIX_depth_texture = GL_TRUE;
     ctx->Extensions.SGIX_shadow = GL_TRUE;
     ctx->Extensions.SGIX_shadow_ambient = GL_TRUE;
  #if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
diff --combined src/mesa/main/mtypes.h
index 8bf6858c1e3ca7883356c18062ca68c0d03cf7dd,62bc65cc72cc0729a58b7ad0c5066f953cbb1ed8..052da2c18e18e2f7a3bef15a86b5904803c1fc3d
@@@ -126,8 -126,6 +126,8 @@@ struct gl_program_cache
  struct gl_texture_format;
  struct gl_texture_image;
  struct gl_texture_object;
 +struct st_context;
 +struct pipe_surface;
  typedef struct __GLcontextRec GLcontext;
  typedef struct __GLcontextModesRec GLvisual;
  typedef struct gl_framebuffer GLframebuffer;
@@@ -1569,6 -1567,7 +1569,6 @@@ struct gl_texture_attri
  
     struct gl_texture_unit Unit[MAX_TEXTURE_UNITS];
  
 -   /** Proxy texture objects */
     struct gl_texture_object *ProxyTex[NUM_TEXTURE_TARGETS];
  
     /** GL_EXT_shared_texture_palette */
@@@ -2260,7 -2259,6 +2260,7 @@@ struct gl_renderbuffe
     GLubyte IndexBits;
     GLubyte DepthBits;
     GLubyte StencilBits;
 +   GLubyte Samples;     /**< Number of samples - 0 if not multisampled */
     GLvoid *Data;        /**< This may not be used by some kinds of RBs */
  
     /* Used to wrap one renderbuffer around another: */
@@@ -2628,7 -2626,6 +2628,6 @@@ struct gl_extension
     GLboolean SGIS_generate_mipmap;
     GLboolean SGIS_texture_edge_clamp;
     GLboolean SGIS_texture_lod;
-    GLboolean SGIX_depth_texture;
     GLboolean SGIX_shadow;
     GLboolean SGIX_shadow_ambient; /* or GL_ARB_shadow_ambient */
     GLboolean TDFX_texture_compression_FXT1;
@@@ -2722,7 -2719,6 +2721,7 @@@ struct gl_matrix_stac
  #define _NEW_MULTISAMPLE        0x2000000  /**< __GLcontextRec::Multisample */
  #define _NEW_TRACK_MATRIX       0x4000000  /**< __GLcontextRec::VertexProgram */
  #define _NEW_PROGRAM            0x8000000  /**< __GLcontextRec::VertexProgram */
 +#define _NEW_CURRENT_ATTRIB     0x10000000  /**< __GLcontextRec::Current */
  #define _NEW_ALL ~0
  /*@}*/
  
@@@ -3050,8 -3046,6 +3049,8 @@@ struct __GLcontextRe
     GLenum RenderMode;        /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */
     GLbitfield NewState;      /**< bitwise-or of _NEW_* flags */
  
 +   GLbitfield varying_vp_inputs;  /**< mask of VERT_BIT_* flags */
 +
     /** \name Derived state */
     /*@{*/
     /** Bitwise-or of DD_* flags.  Note that this bitfield may be used before
     void *swsetup_context;
     void *swtnl_context;
     void *swtnl_im;
 -   void *acache_context;
 +   struct st_context *st;
     void *aelt_context;
     /*@}*/
  };
diff --combined src/mesa/main/state.c
index 7e44310d8d37f83503bf86692228a36416a819bd,48656bd35eef35ce6c2b14c3926624310b99e166..2f0e7cc368eeee8ad86d3cf850a412fabba219e9
@@@ -258,12 -258,6 +258,6 @@@ update_program(GLcontext *ctx
        }
     }
  
-    if (ctx->VertexProgram._Current)
-       assert(ctx->VertexProgram._Current->Base.Parameters);
-    if (ctx->FragmentProgram._Current)
-       assert(ctx->FragmentProgram._Current->Base.Parameters);
     /* XXX: get rid of _Active flag.
      */
  #if 1
@@@ -447,9 -441,6 +441,9 @@@ _mesa_update_state_locked( GLcontext *c
     GLbitfield new_state = ctx->NewState;
     GLbitfield prog_flags = _NEW_PROGRAM;
  
 +   if (new_state == _NEW_CURRENT_ATTRIB) 
 +      goto out;
 +
     if (MESA_VERBOSE & VERBOSE_STATE)
        _mesa_print_state("_mesa_update_state", new_state);
  
     if (new_state & (_NEW_PROGRAM|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX))
        _mesa_update_texture( ctx, new_state );
  
 -   if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL))
 +   if (new_state & _NEW_BUFFERS)
        _mesa_update_framebuffer(ctx);
  
     if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
        _mesa_update_tnl_spaces( ctx, new_state );
  
     if (ctx->FragmentProgram._MaintainTexEnvProgram) {
 -      prog_flags |= (_NEW_TEXTURE | _NEW_FOG | _DD_NEW_SEPARATE_SPECULAR);
 +      prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE_MATRIX | _NEW_LIGHT |
 +                     _NEW_TEXTURE | _NEW_FOG | _DD_NEW_SEPARATE_SPECULAR);
     }
     if (ctx->VertexProgram._MaintainTnlProgram) {
        prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX |
      * Set ctx->NewState to zero to avoid recursion if
      * Driver.UpdateState() has to call FLUSH_VERTICES().  (fixed?)
      */
 + out:
     new_state = ctx->NewState;
     ctx->NewState = 0;
     ctx->Driver.UpdateState(ctx, new_state);
@@@ -553,38 -542,3 +547,38 @@@ _mesa_update_state( GLcontext *ctx 
     _mesa_update_state_locked(ctx);
     _mesa_unlock_context_textures(ctx);
  }
 +
 +
 +
 +
 +/* Want to figure out which fragment program inputs are actually
 + * constant/current values from ctx->Current.  These should be
 + * referenced as a tracked state variable rather than a fragment
 + * program input, to save the overhead of putting a constant value in
 + * every submitted vertex, transferring it to hardware, interpolating
 + * it across the triangle, etc...
 + *
 + * When there is a VP bound, just use vp->outputs.  But when we're
 + * generating vp from fixed function state, basically want to
 + * calculate:
 + *
 + * vp_out_2_fp_in( vp_in_2_vp_out( varying_inputs ) | 
 + *                 potential_vp_outputs )
 + *
 + * Where potential_vp_outputs is calculated by looking at enabled
 + * texgen, etc.
 + * 
 + * The generated fragment program should then only declare inputs that
 + * may vary or otherwise differ from the ctx->Current values.
 + * Otherwise, the fp should track them as state values instead.
 + */
 +void
 +_mesa_set_varying_vp_inputs( GLcontext *ctx,
 +                             GLbitfield varying_inputs )
 +{
 +   if (ctx->varying_vp_inputs != varying_inputs) {
 +      ctx->varying_vp_inputs = varying_inputs;
 +      ctx->NewState |= _NEW_ARRAY;
 +      //_mesa_printf("%s %x\n", __FUNCTION__, varying_inputs);
 +   }
 +}
index 60f36c4a87faf676441b1b46dec9e6371bfdd06c,4442ce39a447262d62d6ffd8fcbe8fd5499876be..ce2772c2992e5f1c13964bb31b25b22922d8fb85
@@@ -1420,14 -1420,13 +1420,13 @@@ _mesa_choose_tex_format( GLcontext *ctx
           ; /* fallthrough */
     }
  
-    if (ctx->Extensions.SGIX_depth_texture ||
-        ctx->Extensions.ARB_depth_texture) {
+    if (ctx->Extensions.ARB_depth_texture) {
        switch (internalFormat) {
           case GL_DEPTH_COMPONENT:
-          case GL_DEPTH_COMPONENT24_SGIX:
-          case GL_DEPTH_COMPONENT32_SGIX:
+          case GL_DEPTH_COMPONENT24:
+          case GL_DEPTH_COMPONENT32:
              return &_mesa_texformat_z32;
-          case GL_DEPTH_COMPONENT16_SGIX:
+          case GL_DEPTH_COMPONENT16:
              return &_mesa_texformat_z16;
           default:
              ; /* fallthrough */
@@@ -1674,11 -1673,6 +1673,11 @@@ _mesa_format_to_type_and_comps(const st
        *comps = 1; /* XXX OK? */
        return;
  
 +   case MESA_FORMAT_S8_Z24:
 +      *datatype = GL_UNSIGNED_INT;
 +      *comps = 1; /* XXX OK? */
 +      return;
 +
     case MESA_FORMAT_Z16:
        *datatype = GL_UNSIGNED_SHORT;
        *comps = 1;
        *comps = 1;
        return;
  
 +#if FEATURE_EXT_texture_sRGB
     case MESA_FORMAT_SRGB8:
        *datatype = GL_UNSIGNED_BYTE;
        *comps = 3;
        *datatype = GL_UNSIGNED_BYTE;
        *comps = 2;
        return;
 +#endif
  
 +#if FEATURE_texture_fxt1
     case MESA_FORMAT_RGB_FXT1:
     case MESA_FORMAT_RGBA_FXT1:
 +#endif
 +#if FEATURE_texture_s3tc
     case MESA_FORMAT_RGB_DXT1:
     case MESA_FORMAT_RGBA_DXT1:
     case MESA_FORMAT_RGBA_DXT3:
        *datatype = GL_UNSIGNED_BYTE;
        *comps = 0;
        return;
 +#endif
  
     case MESA_FORMAT_RGBA:
        *datatype = CHAN_TYPE;
diff --combined src/mesa/main/teximage.c
index 91c41f38c30ef5e7f6cace5c14b5197c565c8106,4a419fde261ec8f06581b4c6def1f90bbf15dd3d..bf23a1f290dc6f583d14be0960ac8e02f02c1440
@@@ -241,13 -241,12 +241,12 @@@ _mesa_base_tex_format( GLcontext *ctx, 
        }
     }
  
-    if (ctx->Extensions.SGIX_depth_texture ||
-        ctx->Extensions.ARB_depth_texture) {
+    if (ctx->Extensions.ARB_depth_texture) {
        switch (internalFormat) {
           case GL_DEPTH_COMPONENT:
-          case GL_DEPTH_COMPONENT16_SGIX:
-          case GL_DEPTH_COMPONENT24_SGIX:
-          case GL_DEPTH_COMPONENT32_SGIX:
+          case GL_DEPTH_COMPONENT16:
+          case GL_DEPTH_COMPONENT24:
+          case GL_DEPTH_COMPONENT32:
              return GL_DEPTH_COMPONENT;
           default:
              ; /* fallthrough */
@@@ -526,9 -525,9 +525,9 @@@ static GLboolea
  is_depth_format(GLenum format)
  {
     switch (format) {
-       case GL_DEPTH_COMPONENT16_ARB:
-       case GL_DEPTH_COMPONENT24_ARB:
-       case GL_DEPTH_COMPONENT32_ARB:
+       case GL_DEPTH_COMPONENT16:
+       case GL_DEPTH_COMPONENT24:
+       case GL_DEPTH_COMPONENT32:
        case GL_DEPTH_COMPONENT:
           return GL_TRUE;
        default:
@@@ -1216,30 -1215,19 +1215,30 @@@ _mesa_init_teximage_fields(GLcontext *c
     img->Width = width;
     img->Height = height;
     img->Depth = depth;
 +
     img->Width2 = width - 2 * border;   /* == 1 << img->WidthLog2; */
 -   img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
 -   img->Depth2 = depth - 2 * border;   /* == 1 << img->DepthLog2; */
     img->WidthLog2 = logbase2(img->Width2);
 -   if (height == 1)  /* 1-D texture */
 +
 +   if (height == 1) { /* 1-D texture */
 +      img->Height2 = 1;
        img->HeightLog2 = 0;
 -   else
 +   }
 +   else {
 +      img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
        img->HeightLog2 = logbase2(img->Height2);
 -   if (depth == 1)   /* 2-D texture */
 +   }
 +
 +   if (depth == 1) {  /* 2-D texture */
 +      img->Depth2 = 1;
        img->DepthLog2 = 0;
 -   else
 +   }
 +   else {
 +      img->Depth2 = depth - 2 * border;   /* == 1 << img->DepthLog2; */
        img->DepthLog2 = logbase2(img->Depth2);
 +   }
 +
     img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
 +
     img->IsCompressed = GL_FALSE;
     img->CompressedSize = 0;
  
@@@ -2308,8 -2296,7 +2307,7 @@@ _mesa_GetTexImage( GLenum target, GLin
        return;
     }
  
-    if (!ctx->Extensions.SGIX_depth_texture &&
-        !ctx->Extensions.ARB_depth_texture && is_depth_format(format)) {
+    if (!ctx->Extensions.ARB_depth_texture && is_depth_format(format)) {
        _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
        return;
     }
index 448251b223dc59e12fbe1a0c140ceba3bb6d5664,39988b5fca67c6c78afca7b18e8109da5cbb1e5d..536404bf978463fe49ae0e2f2c7aa45b4d0d244f
   * \author Karl Rasche
   */
  
 +/**
 +Notes on program parameters, etc.
 +
 +The instructions we emit will use six kinds of source registers:
 +
 +  PROGRAM_INPUT      - input registers
 +  PROGRAM_TEMPORARY  - temp registers
 +  PROGRAM_ADDRESS    - address/indirect register
 +  PROGRAM_SAMPLER    - texture sampler
 +  PROGRAM_CONSTANT   - indexes into program->Parameters, a known constant/literal
 +  PROGRAM_STATE_VAR  - indexes into program->Parameters, and may actually be:
 +                       + a state variable, like "state.fog.color", or
 +                       + a pointer to a "program.local[k]" parameter, or
 +                       + a pointer to a "program.env[k]" parameter
 +
 +Basically, all the program.local[] and program.env[] values will get mapped
 +into the unified gl_program->Parameters array.  This solves the problem of
 +having three separate program parameter arrays.
 +*/
 +
 +
  #include "main/glheader.h"
  #include "main/imports.h"
  #include "main/context.h"
  #include "shader/grammar/grammar_mesa.h"
  #include "arbprogparse.h"
  #include "program.h"
 +#include "programopt.h"
  #include "prog_parameter.h"
  #include "prog_statevars.h"
  #include "prog_instruction.h"
  
 -
 -/* For ARB programs, use the NV instruction limits */
 -#define MAX_INSTRUCTIONS MAX2(MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS, \
 -                              MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS)
 -
 -
  /**
   * This is basically a union of the vertex_program and fragment_program
   * structs that we can use to parse the program into
@@@ -1886,11 -1870,7 +1886,11 @@@ parse_param_elements (GLcontext * ctx, 
                                          const_values, 4);
           if (param_var->param_binding_begin == ~0U)
              param_var->param_binding_begin = idx;
 -         param_var->param_binding_type = PROGRAM_CONSTANT;
 +         param_var->param_binding_type = PROGRAM_STATE_VAR;
 +         /* Note: when we reference this parameter in an instruction later,
 +          * we'll check if it's really a constant/immediate and set the
 +          * instruction register type appropriately.
 +          */
           param_var->param_binding_length++;
           Program->Base.NumParameters++;
           break;
@@@ -2597,18 -2577,6 +2597,18 @@@ parse_src_reg (GLcontext * ctx, const G
           return 1;
     }
  
 +   if (*File == PROGRAM_STATE_VAR) {
 +      enum register_file file;
 +
 +      /* If we're referencing the Program->Parameters[] array, check if the
 +       * parameter is really a constant/literal.  If so, set File to CONSTANT.
 +       */
 +      assert(*Index < (GLint) Program->Base.Parameters->NumParameters);
 +      file = Program->Base.Parameters->Parameters[*Index].Type;
 +      if (file == PROGRAM_CONSTANT)
 +         *File = PROGRAM_CONSTANT;
 +   }
 +
     /* Add attributes to InputsRead only if they are used the program.
      * This avoids the handling of unused ATTRIB declarations in the drivers. */
     if (*File == PROGRAM_INPUT)
@@@ -3385,11 -3353,11 +3385,11 @@@ debug_variables (GLcontext * ctx, struc
                 fprintf (stderr, "%s\n",
                          Program->Base.Parameters->Parameters[a + b].Name);
                 if (Program->Base.Parameters->Parameters[a + b].Type == PROGRAM_STATE_VAR) {
 -                  const char *s;
 +                  char *s;
                    s = _mesa_program_state_string(Program->Base.Parameters->Parameters
                                                   [a + b].StateIndexes);
                    fprintf(stderr, "%s\n", s);
 -                  _mesa_free((char *) s);
 +                  _mesa_free(s);
                 }
                 else
                    fprintf (stderr, "%f %f %f %f\n",
@@@ -3437,7 -3405,7 +3437,7 @@@ parse_instructions(GLcontext * ctx, con
        : ctx->Const.VertexProgram.MaxInstructions;
     GLint err = 0;
  
 -   ASSERT(MAX_INSTRUCTIONS >= maxInst);
 +   ASSERT(MAX_PROGRAM_INSTRUCTIONS >= maxInst);
  
     Program->MajorVersion = (GLuint) * inst++;
     Program->MinorVersion = (GLuint) * inst++;
@@@ -3792,7 -3760,7 +3792,7 @@@ _mesa_parse_arb_program(GLcontext *ctx
  
     /* Initialize the arb_program struct */
     program->Base.String = strz;
 -   program->Base.Instructions = _mesa_alloc_instructions(MAX_INSTRUCTIONS);
 +   program->Base.Instructions = _mesa_alloc_instructions(MAX_PROGRAM_INSTRUCTIONS);
     program->Base.NumInstructions =
     program->Base.NumTemporaries =
     program->Base.NumParameters =
  
     _mesa_free (parsed);
  
 -   /* Reallocate the instruction array from size [MAX_INSTRUCTIONS]
 +   /* Reallocate the instruction array from size [MAX_PROGRAM_INSTRUCTIONS]
      * to size [ap.Base.NumInstructions].
      */
     program->Base.Instructions
        = _mesa_realloc_instructions(program->Base.Instructions,
 -                                   MAX_INSTRUCTIONS,
 +                                   MAX_PROGRAM_INSTRUCTIONS,
                                     program->Base.NumInstructions);
  
     return !err;
@@@ -3895,6 -3863,9 +3895,9 @@@ _mesa_parse_arb_fragment_program(GLcont
     program->FogOption          = ap.FogOption;
     program->UsesKill          = ap.UsesKill;
  
+    if (program->FogOption)
+       program->Base.InputsRead |= FRAG_BIT_FOGC;
+       
     if (program->Base.Instructions)
        _mesa_free(program->Base.Instructions);
     program->Base.Instructions = ap.Base.Instructions;
        _mesa_free_parameter_list(program->Base.Parameters);
     program->Base.Parameters    = ap.Base.Parameters;
  
 +   /* Append fog instructions now if the program has "OPTION ARB_fog_exp"
 +    * or similar.  We used to leave this up to drivers, but it appears
 +    * there's no hardware that wants to do fog in a discrete stage separate
 +    * from the fragment shader.
 +    */
 +   if (program->FogOption != GL_NONE) {
 +      _mesa_append_fog_code(ctx, program);
 +      program->FogOption = GL_NONE;
 +   }
 +
  #if DEBUG_FP
     _mesa_printf("____________Fragment program %u ________\n", program->Base.Id);
     _mesa_print_program(&program->Base);
index 5d21cff67210fbb791017944467431b8d5e859ea,738891a0293441f5636151668e74947e6171f9a8..37962f0e9bb33717aef36c7ca48c23f38d5b198f
@@@ -372,7 -372,11 +372,11 @@@ _mesa_reference_program(GLcontext *ctx
     assert(ptr);
     if (*ptr && prog) {
        /* sanity check */
-       ASSERT((*ptr)->Target == prog->Target);
+       if ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB)
+          ASSERT(prog->Target == GL_VERTEX_PROGRAM_ARB);
+       else if ((*ptr)->Target == GL_FRAGMENT_PROGRAM_ARB)
+          ASSERT(prog->Target == GL_FRAGMENT_PROGRAM_ARB ||
+                 prog->Target == GL_FRAGMENT_PROGRAM_NV);
     }
     if (*ptr == prog) {
        return;  /* no change */
@@@ -550,6 -554,7 +554,6 @@@ _mesa_insert_instructions(struct gl_pro
     return GL_TRUE;
  }
  
 -
  /**
   * Delete 'count' instructions at 'start' in the given program.
   * Adjust branch targets accordingly.
@@@ -686,47 -691,17 +690,47 @@@ _mesa_combine_programs(GLcontext *ctx
  
     if (newProg->Target == GL_FRAGMENT_PROGRAM_ARB) {
        struct gl_fragment_program *fprogA, *fprogB, *newFprog;
 +      GLbitfield progB_inputsRead = progB->InputsRead;
 +      GLint progB_colorFile, progB_colorIndex;
 +
        fprogA = (struct gl_fragment_program *) progA;
        fprogB = (struct gl_fragment_program *) progB;
        newFprog = (struct gl_fragment_program *) newProg;
  
        newFprog->UsesKill = fprogA->UsesKill || fprogB->UsesKill;
  
 +      /* We'll do a search and replace for instances
 +       * of progB_colorFile/progB_colorIndex below...
 +       */
 +      progB_colorFile = PROGRAM_INPUT;
 +      progB_colorIndex = FRAG_ATTRIB_COL0;
 +
 +      /*
 +       * The fragment program may get color from a state var rather than
 +       * a fragment input (vertex output) if it's constant.
 +       * See the texenvprogram.c code.
 +       * So, search the program's parameter list now to see if the program
 +       * gets color from a state var instead of a conventional fragment
 +       * input register.
 +       */
 +      for (i = 0; i < progB->Parameters->NumParameters; i++) {
 +         struct gl_program_parameter *p = &progB->Parameters->Parameters[i];
 +         if (p->Type == PROGRAM_STATE_VAR &&
 +             p->StateIndexes[0] == STATE_INTERNAL &&
 +             p->StateIndexes[1] == STATE_CURRENT_ATTRIB &&
 +             p->StateIndexes[2] == VERT_ATTRIB_COLOR0) {
 +            progB_inputsRead |= FRAG_BIT_COL0;
 +            progB_colorFile = PROGRAM_STATE_VAR;
 +            progB_colorIndex = i;
 +            break;
 +         }
 +      }
 +
        /* Connect color outputs of fprogA to color inputs of fprogB, via a
         * new temporary register.
         */
        if ((progA->OutputsWritten & (1 << FRAG_RESULT_COLR)) &&
 -          (progB->InputsRead & (1 << FRAG_ATTRIB_COL0))) {
 +          (progB_inputsRead & FRAG_BIT_COL0)) {
           GLint tempReg = _mesa_find_free_register(newProg, PROGRAM_TEMPORARY);
           if (tempReg < 0) {
              _mesa_problem(ctx, "No free temp regs found in "
           replace_registers(newInst, lenA,
                             PROGRAM_OUTPUT, FRAG_RESULT_COLR,
                             PROGRAM_TEMPORARY, tempReg);
 -         /* replace reads from input.color[0] with tempReg */
 +         /* replace reads from the input color with tempReg */
           replace_registers(newInst + lenA, lenB,
 -                           PROGRAM_INPUT, FRAG_ATTRIB_COL0,
 -                           PROGRAM_TEMPORARY, tempReg);
 +                           progB_colorFile, progB_colorIndex, /* search for */
 +                           PROGRAM_TEMPORARY, tempReg  /* replace with */ );
        }
  
 -      inputsB = progB->InputsRead;
 +      /* compute combined program's InputsRead */
 +      inputsB = progB_inputsRead;
        if (progA->OutputsWritten & (1 << FRAG_RESULT_COLR)) {
           inputsB &= ~(1 << FRAG_ATTRIB_COL0);
        }
index 854f8bfdaa61c215edf03c8a46cefe5980a12cf1,504d7693234a5794c255f4de50a874a1b28e2923..266ecc4ef212fa159df45744a5dc5a96182298d7
@@@ -47,7 -47,7 +47,7 @@@
  #include "shader/shader_api.h"
  #include "shader/slang/slang_compile.h"
  #include "shader/slang/slang_link.h"
+ #include "glapi/dispatch.h"
  
  
  #ifndef GL_PROGRAM_BINARY_LENGTH_OES
@@@ -381,7 -381,7 +381,7 @@@ _mesa_init_shader_state(GLcontext * ctx
      * are generated by the GLSL compiler.
      */
     ctx->Shader.EmitHighLevelInstructions = GL_TRUE;
 -   ctx->Shader.EmitCondCodes = GL_TRUE; /* XXX probably want GL_FALSE... */
 +   ctx->Shader.EmitCondCodes = GL_FALSE;/*GL_TRUE;*/ /* XXX probably want GL_FALSE... */
     ctx->Shader.EmitComments = GL_FALSE;
  }
  
@@@ -455,7 -455,13 +455,13 @@@ _mesa_attach_shader(GLcontext *ctx, GLu
     n = shProg->NumShaders;
     for (i = 0; i < n; i++) {
        if (shProg->Shaders[i] == sh) {
-          /* already attached */
+          /* The shader is already attched to this program.  The
+           * GL_ARB_shader_objects spec says:
+           *
+           *     "The error INVALID_OPERATION is generated by AttachObjectARB
+           *     if <obj> is already attached to <containerObj>."
+           */
+          _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
           return;
        }
     }
@@@ -919,24 -925,15 +925,15 @@@ _mesa_get_attached_shaders(GLcontext *c
  static GLuint
  _mesa_get_handle(GLcontext *ctx, GLenum pname)
  {
- #if 0
-    GET_CURRENT_CONTEXT(ctx);
-    switch (pname) {
-    case GL_PROGRAM_OBJECT_ARB:
-       {
-          struct gl2_program_intf **pro = ctx->Shader.CurrentProgram;
-          if (pro != NULL)
-             return (**pro)._container._generic.
-                GetName((struct gl2_generic_intf **) (pro));
-       }
-       break;
-    default:
+    GLint handle = 0;
+    
+    if (pname == GL_PROGRAM_OBJECT_ARB) {
+       CALL_GetIntegerv(ctx->Exec, (GL_CURRENT_PROGRAM, &handle));
+    } else {
        _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
     }
- #endif
-    return 0;
+    return handle;
  }
  
  
@@@ -1120,8 -1117,7 +1117,8 @@@ get_matrix_dims(GLenum type, GLint *row
  
  /**
   * Determine the number of rows and columns occupied by a uniform
 - * according to its datatype.
 + * according to its datatype.  For non-matrix types (such as GL_FLOAT_VEC4),
 + * the number of rows = 1 and cols = number of elements in the vector.
   */
  static void
  get_uniform_rows_cols(const struct gl_program_parameter *p,
     get_matrix_dims(p->DataType, rows, cols);
     if (*rows == 0 && *cols == 0) {
        /* not a matrix type, probably a float or vector */
 -      *rows = p->Size / 4 + 1;
 -      if (p->Size % 4 == 0)
 -         *cols = 4;
 -      else
 -         *cols = p->Size % 4;
 +      if (p->Size <= 4) {
 +         *rows = 1;
 +         *cols = p->Size;
 +      }
 +      else {
 +         *rows = p->Size / 4 + 1;
 +         if (p->Size % 4 == 0)
 +            *cols = 4;
 +         else
 +            *cols = p->Size % 4;
 +      }
     }
  }
  
@@@ -1523,7 -1513,7 +1520,7 @@@ set_program_uniform(GLcontext *ctx, str
        return;
     }
  
 -   if (index + offset > program->Parameters->Size) {
 +   if (index + offset > (GLint) program->Parameters->Size) {
        /* out of bounds! */
        return;
     }
           /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
           if (is_boolean_type(program->Parameters->Parameters[index].DataType)) {
              for (i = 0; i < elems; i++) {
 -               uniformVal[i] = uniformVal[i] ? 1.0 : 0.0;
 +               uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
              }
           }
        }