merge of glsl-compiler-1 branch
authorBrian <brian@yutani.localnet.net>
Mon, 26 Mar 2007 16:13:02 +0000 (10:13 -0600)
committerBrian <brian@yutani.localnet.net>
Mon, 26 Mar 2007 16:13:02 +0000 (10:13 -0600)
1  2 
src/mesa/drivers/dri/i965/brw_wm_fp.c
src/mesa/drivers/dri/r300/r300_context.c
src/mesa/drivers/dri/r300/r300_fragprog.c
src/mesa/drivers/dri/r300/r300_state.c
src/mesa/main/texenvprogram.c
src/mesa/tnl/t_vp_build.c

index ba2dbeccde2165eaa5d8760d42b428b07e9dfe30,47ddcd0f05e2cd292ae7c274c8a313e3d59dd11f..ff97d87dc45210f7f4ad1f5209b27e209dbcf62f
  #include "brw_wm.h"
  #include "brw_util.h"
  
- #include "shader/program.h"
- #include "shader/program_instruction.h"
- #include "shader/arbprogparse.h"
+ #include "shader/prog_parameter.h"
+ #include "shader/prog_print.h"
+ #include "shader/prog_statevars.h"
  
  #define FIRST_INTERNAL_TEMP MAX_NV_FRAGMENT_PROGRAM_TEMPS
  
@@@ -370,23 -371,21 +371,21 @@@ static void emit_interp( struct brw_wm_
   * harm and it's not as if the parameter handling isn't a big hack
   * anyway.
   */
- static struct prog_src_register search_or_add_param6( struct brw_wm_compile *c, 
-                                            GLint s0,
-                                            GLint s1,
-                                            GLint s2,
-                                            GLint s3,
-                                            GLint s4,
-                                            GLint s5)
+ static struct prog_src_register search_or_add_param5(struct brw_wm_compile *c, 
+                                                      GLint s0,
+                                                      GLint s1,
+                                                      GLint s2,
+                                                      GLint s3,
+                                                      GLint s4)
  {
     struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters;
-    GLint tokens[6];
+    gl_state_index tokens[STATE_LENGTH];
     GLuint idx;
     tokens[0] = s0;
     tokens[1] = s1;
     tokens[2] = s2;
     tokens[3] = s3;
     tokens[4] = s4;
-    tokens[5] = s5;
     
     for (idx = 0; idx < paramList->NumParameters; idx++) {
        if (paramList->Parameters[idx].Type == PROGRAM_STATE_VAR &&
  
     /* Recalculate state dependency: 
      */
 -   c->fp->param_state = brw_parameter_list_state_flags( paramList );
 +   c->fp->param_state = paramList->StateFlags;
  
     return src_reg(PROGRAM_STATE_VAR, idx);
  }
@@@ -413,6 -412,7 +412,7 @@@ static struct prog_src_register search_
     struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters;
     GLfloat values[4];
     GLuint idx;
+    GLuint swizzle;
  
     values[0] = s0;
     values[1] = s1;
         return src_reg(PROGRAM_STATE_VAR, idx);
     }
     
-    idx = _mesa_add_unnamed_constant( paramList, values, 4 );
+    idx = _mesa_add_unnamed_constant( paramList, values, 4, &swizzle );
+    /* XXX what about swizzle? */
     return src_reg(PROGRAM_STATE_VAR, idx);
  }
  
@@@ -527,11 -527,11 +527,11 @@@ static void precalc_tex( struct brw_wm_
  
     if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) {
        struct prog_src_register scale = 
-        search_or_add_param6( c, 
+        search_or_add_param5( c, 
                               STATE_INTERNAL, 
                               STATE_TEXRECT_SCALE,
                               inst->TexSrcUnit,
-                              0,0,0 );
+                              0,0 );
  
        tmpcoord = get_temp(c);
  
@@@ -724,7 -724,7 +724,7 @@@ static void fog_blend( struct brw_wm_co
                             struct prog_src_register fog_factor )
  {
     struct prog_dst_register outcolor = dst_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);
-    struct prog_src_register fogcolor = search_or_add_param6( c, STATE_FOG_COLOR, 0,0,0,0,0 );
+    struct prog_src_register fogcolor = search_or_add_param5( c, STATE_FOG_COLOR, 0,0,0,0 );
  
     /* color.xyz = LRP fog_factor.xxxx, output_color, fog_color */
     
index 68c8f5b87d0c65f6d54127e8550761172e1da0cd,8aaf50b6d81783a0bca051871139119b7453a719..1f8d95078fbe9a7e29ca7e1355a06147476f65ce
@@@ -133,6 -133,7 +133,6 @@@ const struct dri_extension stencil_two_
  
  extern struct tnl_pipeline_stage _r300_render_stage;
  extern const struct tnl_pipeline_stage _r300_tcl_stage;
 -extern const struct tnl_pipeline_stage _r300_texrect_stage;
  
  static const struct tnl_pipeline_stage *r300_pipeline[] = {
  
  
        /* Else do them here.
         */
 -      /* scale texture rectangle to 0..1. */
 -      &_r300_texrect_stage,
        &_r300_render_stage,
        &_tnl_render_stage,     /* FALLBACK  */
        0,
@@@ -201,7 -204,7 +201,7 @@@ GLboolean r300CreateContext(const __GLc
                                                     "def_max_anisotropy");
  
        //r300->texmicrotile = GL_TRUE;
 -      
 +
        /* Init default driver functions then plug in our R300-specific functions
         * (the texture functions are especially important)
         */
        r300InitStateFuncs(&functions);
        r300InitTextureFuncs(&functions);
        r300InitShaderFuncs(&functions);
 -      
 +
  #ifdef USER_BUFFERS
        radeon_mm_init(r300);
  #endif
        if (hw_tcl_on) {
                r300_init_vbo_funcs(&functions);
        }
 -#endif        
 +#endif
        if (!radeonInitContext(&r300->radeon, &functions,
                               glVisual, driContextPriv, sharedContextPrivate)) {
                FREE(r300);
         * texturable memory at once.
         */
  
 -      ctx = r300->radeon.glCtx; 
 -      
 +      ctx = r300->radeon.glCtx;
 +
        ctx->Const.MaxTextureImageUnits = driQueryOptioni(&r300->radeon.optionCache,
                                                     "texture_image_units");
        ctx->Const.MaxTextureCoordUnits = driQueryOptioni(&r300->radeon.optionCache,
        ctx->Const.MinLineWidthAA = 1.0;
        ctx->Const.MaxLineWidth = R300_LINESIZE_MAX;
        ctx->Const.MaxLineWidthAA = R300_LINESIZE_MAX;
 -      
 +
  #ifdef USER_BUFFERS
        /* Needs further modifications */
  #if 0
        ctx->Const.FragmentProgram.MaxNativeTexIndirections = PFS_MAX_TEX_INDIRECT;
        ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* and these are?? */
        _tnl_ProgramCacheInit(ctx);
-       ctx->_MaintainTexEnvProgram = GL_TRUE;
+       ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
  
        driInitExtensions(ctx, card_extensions, GL_TRUE);
 -      
 +
        if (driQueryOptionb(&r300->radeon.optionCache, "disable_stencil_two_side") == 0)
                driInitSingleExtension(ctx, stencil_two_side);
 -      
 +
        if (r300->radeon.glCtx->Mesa_DXTn && !driQueryOptionb (&r300->radeon.optionCache, "disable_s3tc")) {
          _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
          _mesa_enable_extension( ctx, "GL_S3_s3tc" );
        radeonInitSpanFuncs(ctx);
        r300InitCmdBuf(r300);
        r300InitState(r300);
 -      
 +
  #ifdef RADEON_VTXFMT_A
        radeon_init_vtxfmt_a(r300);
  #endif
@@@ -404,9 -407,9 +404,9 @@@ static void r300FreeGartAllocations(r30
        /* Cannot flush/lock if no context exists. */
        if (in_use)
                r300FlushCmdBuf(r300, __FUNCTION__);
 -      
 +
        done_age = radeonGetAge((radeonContextPtr)r300);
 -      
 +
        for (i = r300->rmm->u_last; i > 0; i--) {
                if (r300->rmm->u_list[i].ptr == NULL) {
                        continue;
                }
  
                assert(r300->rmm->u_list[i].h_pending == 0);
 -              
 +
                tries = 0;
                while(r300->rmm->u_list[i].age > done_age && tries++ < 1000) {
                        usleep(10);
                if (tries >= 1000) {
                        WARN_ONCE("Failed to idle region!");
                }
 -              
 +
                memfree.region_offset = (char *)r300->rmm->u_list[i].ptr -
                        (char *)r300->radeon.radeonScreen->gartTextures.map;
 -              
 +
                ret = drmCommandWrite(r300->radeon.radeonScreen->driScreen->fd,
                                DRM_RADEON_FREE, &memfree, sizeof(memfree));
                if (ret) {
                } else {
                        if (i == r300->rmm->u_last)
                                r300->rmm->u_last--;
 -                      
 +
                        r300->rmm->u_list[i].pending = 0;
                        r300->rmm->u_list[i].ptr = NULL;
                        if (r300->rmm->u_list[i].fb) {
@@@ -487,12 -490,12 +487,12 @@@ void r300DestroyContext(__DRIcontextPri
                _tnl_DestroyContext(r300->radeon.glCtx);
                _vbo_DestroyContext(r300->radeon.glCtx);
                _swrast_DestroyContext(r300->radeon.glCtx);
 -              
 +
                if (r300->dma.current.buf) {
                        r300ReleaseDmaRegion(r300, &r300->dma.current, __FUNCTION__ );
  #ifndef USER_BUFFERS
                        r300FlushCmdBuf(r300, __FUNCTION__);
 -#endif  
 +#endif
                }
                r300FreeGartAllocations(r300);
                r300DestroyCmdBuf(r300);
index e01f56d99dfdc6be677029ec0aabfa9c4c691b4b,c407dfb5b0bc1a98fccfb36cbe22a0a802f7c360..77f95605e4daedca0c083fda0f5514ad2947c988
  #include "glheader.h"
  #include "macros.h"
  #include "enums.h"
+ #include "shader/prog_instruction.h"
+ #include "shader/prog_parameter.h"
+ #include "shader/prog_print.h"
  
- #include "program.h"
- #include "program_instruction.h"
  #include "r300_context.h"
  #include "r300_fragprog.h"
  #include "r300_reg.h"
@@@ -929,47 -930,13 +930,47 @@@ static void emit_tex(struct r300_fragme
        COMPILE_STATE;
        GLuint coord = t_src(rp, fpi->SrcReg[0]);
        GLuint dest = undef, rdest = undef;
 -      GLuint din = cs->dest_in_node, uin = cs->used_in_node;
 +      GLuint din, uin;
        int unit = fpi->TexSrcUnit;
        int hwsrc, hwdest;
 +      GLuint tempreg = 0;
 +
 +      uin = cs->used_in_node;
 +      din = cs->dest_in_node;
  
        /* Resolve source/dest to hardware registers */
 -      hwsrc = t_hw_src(rp, coord, GL_TRUE);
        if (opcode != R300_FPITX_OP_KIL) {
 +              if (fpi->TexSrcTarget == TEXTURE_RECT_INDEX) {
 +                      /**
 +                       * Hardware uses [0..1]x[0..1] range for rectangle textures
 +                       * instead of [0..Width]x[0..Height].
 +                       * Add a scaling instruction.
 +                       *
 +                       * \todo Refactor this once we have proper rewriting/optimization
 +                       * support for programs.
 +                       */
 +                      GLint tokens[6] = { STATE_INTERNAL, STATE_R300_TEXRECT_FACTOR, 0, 0, 0, 0 };
 +                      int factor_index;
 +                      GLuint factorreg;
 +
 +                      tokens[2] = unit;
 +                      factor_index = _mesa_add_state_reference(rp->mesa_program.Base.Parameters, tokens);
 +                      factorreg = emit_const4fv(rp,
 +                                      rp->mesa_program.Base.Parameters->ParameterValues[factor_index]);
 +                      tempreg = keep(get_temp_reg(rp));
 +
 +                      emit_arith(rp, PFS_OP_MAD, tempreg, WRITEMASK_XYZW,
 +                                 coord, factorreg, pfs_zero, 0);
 +
 +                      /* Ensure correct node indirection */
 +                      uin = cs->used_in_node;
 +                      din = cs->dest_in_node;
 +
 +                      hwsrc = t_hw_src(rp, tempreg, GL_TRUE);
 +              } else {
 +                      hwsrc = t_hw_src(rp, coord, GL_TRUE);
 +              }
 +
                dest = t_dst(rp, fpi->DstReg);
  
                /* r300 doesn't seem to be able to do TEX->output reg */
        } else {
                hwdest = 0;
                unit = 0;
 +              hwsrc = t_hw_src(rp, coord, GL_TRUE);
        }
  
 +
        /* Indirection if source has been written in this node, or if the
         * dest has been read/written in this node
         */
                           pfs_one, pfs_zero, 0);
                free_temp(rp, dest);
        }
 +
 +      /* Free temp register */
 +      if (tempreg != 0)
 +              free_temp(rp, tempreg);
  }
  
  
index 17658efdb2f38215955af0ed1870146b9d3f9518,fff11653de1451faa6f34961c15c17ef148a6840..ff3c51c5edf02b484912fa0532392842b90c6a36
@@@ -46,6 -46,8 +46,8 @@@ WITH THE SOFTWARE OR THE USE OR OTHER D
  #include "api_arrayelt.h"
  #include "swrast/swrast.h"
  #include "swrast_setup/swrast_setup.h"
+ #include "shader/prog_parameter.h"
+ #include "shader/prog_statevars.h"
  #include "vbo/vbo.h"
  #include "tnl/tnl.h"
  #include "texformat.h"
@@@ -357,7 -359,7 +359,7 @@@ static void update_alpha(GLcontext *ctx
        GLboolean really_enabled = ctx->Color.AlphaEnabled;
  
        CLAMPED_FLOAT_TO_UBYTE(refByte, ctx->Color.AlphaRef);
 -      
 +
        switch (ctx->Color.AlphaFunc) {
        case GL_NEVER:
                pp_misc |= R300_ALPHA_TEST_FAIL;
                really_enabled = GL_FALSE;
                break;
        }
 -      
 +
        if (really_enabled) {
                pp_misc |= R300_ALPHA_TEST_ENABLE;
                pp_misc |= (refByte & R300_REF_ALPHA_MASK);
        } else {
                pp_misc = 0x0;
        }
 -      
 -      
 +
 +
        R300_STATECHANGE(r300, at);
        r300->hw.at.cmd[R300_AT_ALPHA_TEST] = pp_misc;
        update_early_z(ctx);
@@@ -436,19 -438,19 +438,19 @@@ static void update_depth(GLcontext* ctx
        R300_STATECHANGE(r300, zs);
        r300->hw.zs.cmd[R300_ZS_CNTL_0] &= R300_RB3D_STENCIL_ENABLE;
        r300->hw.zs.cmd[R300_ZS_CNTL_1] &= ~(R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
 -      
 +
        if (ctx->Depth.Test && ctx->Depth.Func != GL_NEVER) {
                if (ctx->Depth.Mask)
                        r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_RB3D_Z_TEST_AND_WRITE;
                else
                        r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_RB3D_Z_TEST;
 -              
 +
                r300->hw.zs.cmd[R300_ZS_CNTL_1] |= translate_func(ctx->Depth.Func) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
        } else {
                r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_RB3D_Z_DISABLED_1;
                r300->hw.zs.cmd[R300_ZS_CNTL_1] |= translate_func(GL_NEVER) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT;
        }
 -      
 +
        update_early_z(ctx);
  }
  
@@@ -479,7 -481,7 +481,7 @@@ static void r300Enable(GLcontext* ctx, 
                if (state) {
                        r300->hw.fogs.cmd[R300_FOGS_STATE] |=
                            R300_FOG_ENABLE;
 -                      
 +
                        ctx->Driver.Fogfv( ctx, GL_FOG_MODE, NULL );
                        ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
                        ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start );
                        r300->hw.fogs.cmd[R300_FOGS_STATE] &=
                            ~R300_FOG_ENABLE;
                }
 -              
 +
                break;
  
        case GL_ALPHA_TEST:
                } else {
  #if R200_MERGED
                        FALLBACK(&r300->radeon, RADEON_FALLBACK_STENCIL, state);
 -#endif                        
 +#endif
                }
                break;
  
@@@ -553,7 -555,7 +555,7 @@@ static void r300UpdatePolygonMode(GLcon
        if (ctx->Polygon.FrontMode != GL_FILL ||
            ctx->Polygon.BackMode != GL_FILL) {
                GLenum f, b;
 -              
 +
                if (ctx->Polygon.FrontFace == GL_CCW) {
                        f = ctx->Polygon.FrontMode;
                        b = ctx->Polygon.BackMode;
@@@ -671,9 -673,9 +673,9 @@@ static void r300Fogfv( GLcontext *ctx, 
  {
        r300ContextPtr r300 = R300_CONTEXT(ctx);
        union { int i; float f; } fogScale, fogStart;
 -      
 +
        (void) param;
 -      
 +
        fogScale.i = r300->hw.fogp.cmd[R300_FOGP_SCALE];
        fogStart.i = r300->hw.fogp.cmd[R300_FOGP_START];
  
@@@ -769,7 -771,7 +771,7 @@@ static void r300PointSize(GLcontext * c
        size = ctx->Point._Size;
  
        R300_STATECHANGE(r300, ps);
 -      r300->hw.ps.cmd[R300_PS_POINTSIZE] = 
 +      r300->hw.ps.cmd[R300_PS_POINTSIZE] =
                ((int)(size * 6) << R300_POINTSIZE_X_SHIFT) |
                ((int)(size * 6) << R300_POINTSIZE_Y_SHIFT);
  }
@@@ -792,7 -794,7 +794,7 @@@ static void r300PolygonMode(GLcontext *
  {
        (void)face;
        (void)mode;
 -      
 +
        r300UpdatePolygonMode(ctx);
  }
  
@@@ -829,7 -831,7 +831,7 @@@ static int translate_stencil_op(int op
  static void r300ShadeModel(GLcontext * ctx, GLenum mode)
  {
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
 -      
 +
        R300_STATECHANGE(rmesa, shade);
        switch (mode) {
        case GL_FLAT:
@@@ -849,7 -851,7 +851,7 @@@ static void r300StencilFuncSeparate(GLc
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
        GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << R300_RB3D_ZS2_STENCIL_REF_SHIFT) |
                          ((ctx->Stencil.ValueMask[0] & 0xff) << R300_RB3D_ZS2_STENCIL_MASK_SHIFT));
 -                        
 +
        GLuint flag;
  
        R300_STATECHANGE(rmesa, zs);
        rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= ~(
                (R300_ZS_MASK << R300_RB3D_ZS1_FRONT_FUNC_SHIFT)
                | (R300_ZS_MASK << R300_RB3D_ZS1_BACK_FUNC_SHIFT));
 -      
 +
        rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &=  ~((R300_RB3D_ZS2_STENCIL_MASK << R300_RB3D_ZS2_STENCIL_REF_SHIFT) |
                                                (R300_RB3D_ZS2_STENCIL_MASK << R300_RB3D_ZS2_STENCIL_MASK_SHIFT));
 -      
 +
        flag = translate_func(ctx->Stencil.Function[0]);
        rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_FRONT_FUNC_SHIFT);
 -      
 +
        if (ctx->Stencil._TestTwoSide)
                flag = translate_func(ctx->Stencil.Function[1]);
 -      
 +
        rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_BACK_FUNC_SHIFT);
        rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= refmask;
  }
@@@ -888,16 -890,16 +890,16 @@@ static void r300StencilOpSeparate(GLcon
  
        R300_STATECHANGE(rmesa, zs);
                /* It is easier to mask what's left.. */
 -      rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= 
 -          (R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT) | 
 -          (R300_ZS_MASK << R300_RB3D_ZS1_FRONT_FUNC_SHIFT) | 
 +      rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &=
 +          (R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT) |
 +          (R300_ZS_MASK << R300_RB3D_ZS1_FRONT_FUNC_SHIFT) |
            (R300_ZS_MASK << R300_RB3D_ZS1_BACK_FUNC_SHIFT);
  
        rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
                 (translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT)
                |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT)
                |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT);
 -      
 +
        if (ctx->Stencil._TestTwoSide) {
                rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
                         (translate_stencil_op(ctx->Stencil.FailFunc[1]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT)
@@@ -992,7 -994,7 +994,7 @@@ void r300UpdateViewportOffset( GLcontex
        R300_STATECHANGE( rmesa, vpt );
        rmesa->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(tx);
        rmesa->hw.vpt.cmd[R300_VPT_YOFFSET] = r300PackFloat32(ty);
 -      
 +
        }
  
        radeonUpdateScissor( ctx );
@@@ -1028,16 -1030,16 +1030,16 @@@ r300UpdateDrawBuffer(GLcontext *ctx
  
  
        R300_STATECHANGE( rmesa, cb );
 -      
 +
        r300->hw.cb.cmd[R300_CB_OFFSET] = drb->flippedOffset + //r300->radeon.state.color.drawOffset +
                r300->radeon.radeonScreen->fbLocation;
        r300->hw.cb.cmd[R300_CB_PITCH] = drb->flippedPitch;//r300->radeon.state.color.drawPitch;
 -      
 +
        if (r300->radeon.radeonScreen->cpp == 4)
                r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_ARGB8888;
        else
                r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_RGB565;
 -      
 +
        if (r300->radeon.sarea->tiling_enabled)
                r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_TILE_ENABLE;
  #if 0
                = ((drb->flippedOffset + rmesa->r200Screen->fbLocation)
                & R200_COLOROFFSET_MASK);
        rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = drb->flippedPitch;
 -      
 +
        if (rmesa->sarea->tiling_enabled) {
                rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE;
        }
  #endif
  }
  
- static void r300FetchStateParameter(GLcontext *ctx, const enum state_index state[],
-                   GLfloat *value)
+ static void
+ r300FetchStateParameter(GLcontext *ctx,
+                         const gl_state_index state[STATE_LENGTH],
+                         GLfloat *value)
  {
 -    r300ContextPtr r300 = R300_CONTEXT(ctx);
 +      r300ContextPtr r300 = R300_CONTEXT(ctx);
  
 -    switch(state[0])
 -    {
 -    case STATE_INTERNAL:
 -      switch(state[1])
 -      {
 -      case STATE_R300_WINDOW_DIMENSION:
 -          value[0] = r300->radeon.dri.drawable->w*0.5f;/* width*0.5 */
 -          value[1] = r300->radeon.dri.drawable->h*0.5f;/* height*0.5 */
 -          value[2] = 0.5F;                            /* for moving range [-1 1] -> [0 1] */
 -          value[3] = 1.0F;                            /* not used */
 -          break;
 -      default:;
 +      switch(state[0]) {
 +      case STATE_INTERNAL:
 +              switch(state[1]) {
 +              case STATE_R300_WINDOW_DIMENSION:
 +                      value[0] = r300->radeon.dri.drawable->w*0.5f;/* width*0.5 */
 +                      value[1] = r300->radeon.dri.drawable->h*0.5f;/* height*0.5 */
 +                      value[2] = 0.5F;                                /* for moving range [-1 1] -> [0 1] */
 +                      value[3] = 1.0F;                                /* not used */
 +                      break;
 +
 +              case STATE_R300_TEXRECT_FACTOR: {
 +                      struct gl_texture_object* t = ctx->Texture.Unit[state[2]].CurrentRect;
 +
 +                      if (t && t->Image[0][t->BaseLevel]) {
 +                              struct gl_texture_image* image = t->Image[0][t->BaseLevel];
 +                              value[0] = 1.0 / image->Width2;
 +                              value[1] = 1.0 / image->Height2;
 +                      } else {
 +                              value[0] = 1.0;
 +                              value[1] = 1.0;
 +                      }
 +                      value[2] = 1.0;
 +                      value[3] = 1.0;
 +                      break; }
 +
 +              default:
 +                      break;
 +              }
 +              break;
 +
 +      default:
 +              break;
        }
 -    default:;
 -    }
  }
  
  /**
@@@ -1133,7 -1119,7 +1137,7 @@@ static void r300PolygonOffset(GLcontex
  {
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
        GLfloat constant = units;
 -      
 +
        switch (ctx->Visual.depthBits) {
        case 16:
                constant *= 4.0;
@@@ -1228,7 -1214,7 +1232,7 @@@ void r300_setup_textures(GLcontext *ctx
        r300ContextPtr r300 = R300_CONTEXT(ctx);
        int hw_tmu=0;
        int last_hw_tmu=-1; /* -1 translates into no setup costs for fields */
 -      int tmu_mappings[R300_MAX_TEXTURE_UNITS] = { -1 };
 +      int tmu_mappings[R300_MAX_TEXTURE_UNITS] = { -1, };
        struct r300_fragment_program *rp =
                (struct r300_fragment_program *)
                (char *)ctx->FragmentProgram._Current;
        R300_STATECHANGE(r300, tex.offset);
        R300_STATECHANGE(r300, tex.chroma_key);
        R300_STATECHANGE(r300, tex.border_color);
 -      
 +
        r300->hw.txe.cmd[R300_TXE_ENABLE]=0x0;
  
        mtu = r300->radeon.glCtx->Const.MaxTextureUnits;
  
        /* We cannot let disabled tmu offsets pass DRM */
        for(i=0; i < mtu; i++) {
 -              if(TMU_ENABLED(ctx, i)) {
 -                      
 +              if (ctx->Texture.Unit[i]._ReallyEnabled) {
 +
  #if 0 /* Enables old behaviour */
                        hw_tmu = i;
  #endif
                        tmu_mappings[i] = hw_tmu;
 -                      
 +
                        t=r300->state.texture.unit[i].texobj;
 -                      
 +
                        if((t->format & 0xffffff00)==0xffffff00) {
                                WARN_ONCE("unknown texture format (entry %x) encountered. Help me !\n", t->format & 0xff);
                        }
 -                      
 +
                        if (RADEON_DEBUG & DEBUG_STATE)
                                fprintf(stderr, "Activating texture unit %d\n", i);
 -                      
 +
                        r300->hw.txe.cmd[R300_TXE_ENABLE] |= (1 << hw_tmu);
 -                      
 +
                        r300->hw.tex.filter.cmd[R300_TEX_VALUE_0 + hw_tmu] = gen_fixed_filter(t->filter) | (hw_tmu << 28);
                        /* Currently disabled! */
                        r300->hw.tex.filter_1.cmd[R300_TEX_VALUE_0 + hw_tmu] = 0x0; //0x20501f80;
                        r300->hw.tex.format.cmd[R300_TEX_VALUE_0 + hw_tmu] = t->format;
                        r300->hw.tex.pitch.cmd[R300_TEX_VALUE_0 + hw_tmu] = t->pitch_reg;
                        r300->hw.tex.offset.cmd[R300_TEX_VALUE_0 + hw_tmu] = t->offset;
 -                      
 +
                        if(t->offset & R300_TXO_MACRO_TILE) {
                                WARN_ONCE("macro tiling enabled!\n");
                        }
 -                      
 +
                        if(t->offset & R300_TXO_MICRO_TILE) {
                                WARN_ONCE("micro tiling enabled!\n");
                        }
 -                      
 +
                        r300->hw.tex.chroma_key.cmd[R300_TEX_VALUE_0 + hw_tmu] = 0x0;
                        r300->hw.tex.border_color.cmd[R300_TEX_VALUE_0 + hw_tmu] = t->pp_border_color;
 -                      
 +
                        last_hw_tmu = hw_tmu;
 -                      
 +
                        hw_tmu++;
                }
        }
 -      
 +
        r300->hw.tex.filter.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_FILTER_0, last_hw_tmu + 1);
        r300->hw.tex.filter_1.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_FILTER1_0, last_hw_tmu + 1);
        r300->hw.tex.size.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_SIZE_0, last_hw_tmu + 1);
        r300->hw.tex.offset.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_OFFSET_0, last_hw_tmu + 1);
        r300->hw.tex.chroma_key.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_CHROMA_KEY_0, last_hw_tmu + 1);
        r300->hw.tex.border_color.cmd[R300_TEX_CMD_0] = cmdpacket0(R300_TX_BORDER_COLOR_0, last_hw_tmu + 1);
 -      
 -      
 +
 +
        if (!rp)        /* should only happenen once, just after context is created */
                return;
 -      
 +
        R300_STATECHANGE(r300, fpt);
 -      
 +
        for(i = 0; i < rp->tex.length; i++){
                int unit;
 +              int opcode;
                unsigned long val;
 -              
 +
                unit = rp->tex.inst[i] >> R300_FPITX_IMAGE_SHIFT;
                unit &= 15;
 -              
 +
                val = rp->tex.inst[i];
                val &= ~R300_FPITX_IMAGE_MASK;
 -              
 -              assert(tmu_mappings[unit] >= 0);
 -              
 -              val |= tmu_mappings[unit] << R300_FPITX_IMAGE_SHIFT;
 -              r300->hw.fpt.cmd[R300_FPT_INSTR_0+i] = val;
 +
 +              opcode = (val & R300_FPITX_OPCODE_MASK) >> R300_FPITX_OPCODE_SHIFT;
 +              if (opcode == R300_FPITX_OP_KIL) {
 +                      r300->hw.fpt.cmd[R300_FPT_INSTR_0+i] = val;
 +              } else {
 +                      if (tmu_mappings[unit] >= 0) {
 +                              val |= tmu_mappings[unit] << R300_FPITX_IMAGE_SHIFT;
 +                              r300->hw.fpt.cmd[R300_FPT_INSTR_0+i] = val;
 +                      } else {
 +                              // We get here when the corresponding texture image is incomplete
 +                              // (e.g. incomplete mipmaps etc.)
 +                              r300->hw.fpt.cmd[R300_FPT_INSTR_0+i] = val;
 +                      }
 +              }
        }
 -      
 +
        r300->hw.fpt.cmd[R300_FPT_CMD_0] = cmdpacket0(R300_PFS_TEXI_0, rp->tex.length);
 -      
 +
        if (RADEON_DEBUG & DEBUG_STATE)
                fprintf(stderr, "TX_ENABLE: %08x  last_hw_tmu=%d\n", r300->hw.txe.cmd[R300_TXE_ENABLE], last_hw_tmu);
  }
@@@ -1391,11 -1367,11 +1395,11 @@@ void r300_setup_rs_unit(GLcontext *ctx
        R300_STATECHANGE(r300, ri);
        R300_STATECHANGE(r300, rc);
        R300_STATECHANGE(r300, rr);
 -      
 +
        fp_reg = in_texcoords = col_interp_nr = high_rr = 0;
  
        r300->hw.rr.cmd[R300_RR_ROUTE_1] = 0;
 -      
 +
        if (InputsRead & FRAG_BIT_WPOS){
                for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
                        if (!(InputsRead & (FRAG_BIT_TEX0 << i)))
                InputsRead |= (FRAG_BIT_TEX0 << i);
                InputsRead &= ~FRAG_BIT_WPOS;
        }
 -      
 +
        for (i=0;i<ctx->Const.MaxTextureUnits;i++) {
                r300->hw.ri.cmd[R300_RI_INTERP_0+i] = 0
                                | R300_RS_INTERP_USED
                        }
                        InputsRead &= ~(FRAG_BIT_TEX0<<i);
                        fp_reg++;
 -              } 
 +              }
                /* Need to count all coords enabled at vof */
                if (R300_OUTPUTS_WRITTEN_TEST( OutputsWritten, VERT_RESULT_TEX0+i, _TNL_ATTRIB_TEX(i) ))
                        in_texcoords++;
                col_interp_nr++;
        }
        out:
 -      
 +
        if (InputsRead & FRAG_BIT_COL1) {
                if (!R300_OUTPUTS_WRITTEN_TEST( OutputsWritten, VERT_RESULT_COL1, _TNL_ATTRIB_COLOR1 )) {
                        WARN_ONCE("fragprog wants col1, vp doesn't provide it\n");
                if (high_rr < 1) high_rr = 1;
                col_interp_nr++;
        }
 -      
 +
        /* Need at least one. This might still lock as the values are undefined... */
        if (in_texcoords == 0 && col_interp_nr == 0) {
                r300->hw.rr.cmd[R300_RR_ROUTE_0] |= 0
                                | (fp_reg++ << R300_RS_ROUTE_0_COLOR_DEST_SHIFT);
                col_interp_nr++;
        }
 -      
 +
        r300->hw.rc.cmd[1] = 0
                        | (in_texcoords << R300_RS_CNTL_TC_CNT_SHIFT)
                        | (col_interp_nr << R300_RS_CNTL_CI_CNT_SHIFT)
@@@ -1541,8 -1517,8 +1545,8 @@@ void r300SetupVertexProgram(r300Context
  /* just a skeleton for now.. */
  
  /* Generate a vertex shader that simply transforms vertex and texture coordinates,
 -   while leaving colors intact. Nothing fancy (like lights) 
 -   
 +   while leaving colors intact. Nothing fancy (like lights)
 +
     If implementing lights make a copy first, so it is easy to switch between the two versions */
  static void r300GenerateSimpleVertexShader(r300ContextPtr r300)
  {
        r300->state.vap_param.transform_offset=0x0;  /* transform matrix */
        r300->state.vertex_shader.param_offset=0x0;
        r300->state.vertex_shader.param_count=0x4;  /* 4 vector values - 4x4 matrix */
 -      
 +
        r300->state.vertex_shader.program_start=0x0;
        r300->state.vertex_shader.unknown_ptr1=0x4; /* magic value ? */
        r300->state.vertex_shader.program_end=0x0;
 -      
 +
        r300->state.vertex_shader.unknown_ptr2=0x0; /* magic value */
        r300->state.vertex_shader.unknown_ptr3=0x4; /* magic value */
 -      
 +
        /* Initialize matrix and vector parameters.. these should really be restructured */
        /* TODO: fix vertex_shader structure */
        r300->state.vertex_shader.matrix[0].length=16;
        r300->state.vertex_shader.vector[1].length=0;
        r300->state.vertex_shader.unknown1.length=0;
        r300->state.vertex_shader.unknown2.length=0;
 -      
 +
  #define WRITE_OP(oper,source1,source2,source3)        {\
        r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].op=(oper); \
        r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src1=(source1); \
        }
  
        /* Multiply vertex coordinates with transform matrix */
 -                      
 +
        WRITE_OP(
                EASY_VSF_OP(MUL, 0, ALL, TMP),
                VSF_PARAM(3),
                VSF_ATTR_W(0),
                EASY_VSF_SOURCE(0, W, W, W, W, NONE, NONE)
                )
 -      
 +
        WRITE_OP(
                EASY_VSF_OP(MUL, 1, ALL, RESULT),
                VSF_REG(1),
                VSF_ATTR_UNITY(1),
                VSF_UNITY(1)
                )
 -      
 +
        WRITE_OP(
                EASY_VSF_OP(MAD, 0, ALL, TMP),
                VSF_PARAM(2),
                VSF_ATTR_Z(0),
                VSF_TMP(0)
                )
 -      
 +
        WRITE_OP(
                EASY_VSF_OP(MAD, 0, ALL, TMP),
                VSF_PARAM(1),
                VSF_ATTR_Y(0),
                VSF_TMP(0)
                )
 -      
 +
        WRITE_OP(
                EASY_VSF_OP(MAD, 0, ALL, RESULT),
                VSF_PARAM(0),
                VSF_TMP(0)
                )
        o_reg += 2;
 -      
 +
        for (i = VERT_ATTRIB_COLOR1; i < VERT_ATTRIB_MAX; i++)
                if (r300->state.sw_tcl_inputs[i] != -1) {
                        WRITE_OP(
                                VSF_ATTR_UNITY(r300->state.sw_tcl_inputs[i]),
                                VSF_UNITY(r300->state.sw_tcl_inputs[i])
                                )
 -              
 +
                }
 -      
 +
        r300->state.vertex_shader.program_end--; /* r300 wants program length to be one more - no idea why */
        r300->state.vertex_shader.program.length=(r300->state.vertex_shader.program_end+1)*4;
 -      
 +
        r300->state.vertex_shader.unknown_ptr1=r300->state.vertex_shader.program_end; /* magic value ? */
        r300->state.vertex_shader.unknown_ptr2=r300->state.vertex_shader.program_end; /* magic value ? */
        r300->state.vertex_shader.unknown_ptr3=r300->state.vertex_shader.program_end; /* magic value ? */
 -      
 +
  }
  
  
@@@ -1712,14 -1688,14 +1716,14 @@@ void r300SetupVertexProgram(r300Context
        int inst_count;
        int param_count;
        struct r300_vertex_program *prog=(struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
 -                      
 +
  
        ((drm_r300_cmd_header_t*)rmesa->hw.vpp.cmd)->vpu.count = 0;
        R300_STATECHANGE(rmesa, vpp);
        param_count = r300VertexProgUpdateParams(ctx, (struct r300_vertex_program_cont *)ctx->VertexProgram._Current/*prog*/, (float *)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]);
        bump_vpu_count(rmesa->hw.vpp.cmd, param_count);
        param_count /= 4;
 -      
 +
        /* Reset state, in case we don't use something */
        ((drm_r300_cmd_header_t*)rmesa->hw.vpi.cmd)->vpu.count = 0;
        ((drm_r300_cmd_header_t*)rmesa->hw.vps.cmd)->vpu.count = 0;
@@@ -1758,23 -1734,23 +1762,23 @@@ void r300UpdateShaders(r300ContextPtr r
        GLcontext *ctx;
        struct r300_vertex_program *vp;
        int i;
 -      
 +
        ctx = rmesa->radeon.glCtx;
 -      
 +
        if (rmesa->NewGLState && hw_tcl_on) {
                rmesa->NewGLState = 0;
 -              
 +
                for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
                        rmesa->temp_attrib[i] = TNL_CONTEXT(ctx)->vb.AttribPtr[i];
                        TNL_CONTEXT(ctx)->vb.AttribPtr[i] = &rmesa->dummy_attrib[i];
                }
 -              
 +
                _tnl_UpdateFixedFunctionProgram(ctx);
 -      
 +
                for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
                        TNL_CONTEXT(ctx)->vb.AttribPtr[i] = rmesa->temp_attrib[i];
                }
 -              
 +
                r300_select_vertex_shader(rmesa);
                vp = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
                /*if (vp->translated == GL_FALSE)
                }
                r300UpdateStateParameters(ctx, _NEW_PROGRAM);
        }
 -      
 +
  }
  
  void r300UpdateShaderStates(r300ContextPtr rmesa)
  {
        GLcontext *ctx;
        ctx = rmesa->radeon.glCtx;
 -      
 +
        r300UpdateTextureState(ctx);
  
        r300SetupPixelShader(rmesa);
        r300_setup_textures(ctx);
 -      
 +
        r300SetupVertexShader(rmesa);
        r300_setup_rs_unit(ctx);
  }
  
  /* This is probably wrong for some values, I need to test this
   * some more.  Range checking would be a good idea also..
 - * 
 + *
   * But it works for most things.  I'll fix it later if someone
   * else with a better clue doesn't
   */
@@@ -1845,13 -1821,13 +1849,13 @@@ void r300SetupPixelShader(r300ContextPt
  
        if (!rp)        /* should only happenen once, just after context is created */
                return;
 -      
 +
        r300_translate_fragment_shader(rmesa, rp);
        if (!rp->translated) {
                fprintf(stderr, "%s: No valid fragment shader, exiting\n", __func__);
                return;
        }
 -      
 +
  #define OUTPUT_FIELD(st, reg, field)  \
                R300_STATECHANGE(rmesa, st); \
                for(i=0;i<=rp->alu_end;i++) \
  static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
  {
        r300ContextPtr r300 = R300_CONTEXT(ctx);
 -      
 +
        _swrast_InvalidateState(ctx, new_state);
        _swsetup_InvalidateState(ctx, new_state);
        _vbo_InvalidateState(ctx, new_state);
@@@ -1969,7 -1945,7 +1973,7 @@@ void r300ResetHwState(r300ContextPtr r3
        r300Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test);
        r300DepthMask(ctx, ctx->Depth.Mask);
        r300DepthFunc(ctx, ctx->Depth.Func);
 -      
 +
        /* stencil */
        r300Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
        r300StencilMaskSeparate(ctx, 0, ctx->Stencil.WriteMask[0]);
        r300UpdateTextureState(ctx);
  
  //    r300_setup_routing(ctx, GL_TRUE);
 -      
 +
  #if 0 /* Done in prior to rendering */
        if(hw_tcl_on == GL_FALSE){
                r300EmitArrays(ctx, GL_TRUE); /* Just do the routing */
  
        r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
        r300Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled);
 -              
 +
                /* Initialize magic registers
                 TODO : learn what they really do, or get rid of
                 those we don't have to touch */
  
        r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_0] = 0x66666666;
        r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_1] = 0x06666666;
 -      if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R300) || 
 +      if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R300) ||
             (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R350))
                r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = R300_GB_TILE_ENABLE
                                                        | R300_GB_TILE_PIPE_COUNT_R300
  
        r300PolygonOffset(ctx, ctx->Polygon.OffsetFactor, ctx->Polygon.OffsetUnits);
        r300Enable(ctx, GL_POLYGON_OFFSET_FILL, ctx->Polygon.OffsetFill);
 -      
 +
        r300->hw.unk42C0.cmd[1] = 0x4B7FFFFF;
        r300->hw.unk42C0.cmd[2] = 0x00000000;
  
        r300BlendColor(ctx, ctx->Color.BlendColor);
        r300->hw.blend_color.cmd[2] = 0;
        r300->hw.blend_color.cmd[3] = 0;
 -      
 +
        /* Again, r300ClearBuffer uses this */
        r300->hw.cb.cmd[R300_CB_OFFSET] = r300->radeon.state.color.drawOffset +
                r300->radeon.radeonScreen->fbLocation;
        r300->hw.cb.cmd[R300_CB_PITCH] = r300->radeon.state.color.drawPitch;
 -      
 +
        if (r300->radeon.radeonScreen->cpp == 4)
                r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_ARGB8888;
        else
                r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_RGB565;
 -      
 +
        if (r300->radeon.sarea->tiling_enabled)
                r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_TILE_ENABLE;
 -      
 +
        r300->hw.unk4E50.cmd[1] = 0;
        r300->hw.unk4E50.cmd[2] = 0;
        r300->hw.unk4E50.cmd[3] = 0;
                fprintf(stderr, "Error: Unsupported depth %d... exiting\n",
                        ctx->Visual.depthBits);
                exit(-1);
 -                      
 +
        }
        /* z compress? */
        //r300->hw.zstencil_format.cmd[1] |= R300_DEPTH_FORMAT_UNK32;
 -      
 +
        r300->hw.zstencil_format.cmd[3] = 0x00000003;
        r300->hw.zstencil_format.cmd[4] = 0x00000000;
  
                r300->radeon.radeonScreen->depthOffset +
                r300->radeon.radeonScreen->fbLocation;
        r300->hw.zb.cmd[R300_ZB_PITCH] = r300->radeon.radeonScreen->depthPitch;
 -      
 +
        if (r300->radeon.sarea->tiling_enabled) {
                /* Turn off when clearing buffers ? */
                r300->hw.zb.cmd[R300_ZB_PITCH] |= R300_DEPTH_TILE_ENABLE;
 -      
 +
                if (ctx->Visual.depthBits == 24)
                        r300->hw.zb.cmd[R300_ZB_PITCH] |= R300_DEPTH_MICROTILE_ENABLE;
        }
 -      
 +
        r300->hw.unk4F28.cmd[1] = 0;
  
        r300->hw.unk4F30.cmd[1] = 0;
@@@ -2307,7 -2283,7 +2311,7 @@@ void r300InitState(r300ContextPtr r300
                                         ctx->Visual.depthBits == 24);
  
        memset(&(r300->state.texture), 0, sizeof(r300->state.texture));
 -      
 +
        r300ResetHwState(r300);
  }
  
@@@ -2353,7 -2329,7 +2357,7 @@@ void r300InitStateFuncs(struct dd_funct
  
        functions->PolygonOffset = r300PolygonOffset;
        functions->PolygonMode = r300PolygonMode;
 -      
 +
        functions->RenderMode = r300RenderMode;
  }
  
index d1994f76d1b70167a3f1ce30d48de149368b0bed,54ae7ce0a13002f3a165bfab091cd1ceaec00f4f..0c6fa82f112f35fd5f699c737e21a00fd7730cf3
  #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.
@@@ -410,31 -411,29 +411,29 @@@ static void release_temps( struct texen
  }
  
  
- static struct ureg register_param6( struct texenv_fragment_program *p, 
+ static struct ureg register_param5( struct texenv_fragment_program *p, 
                                    GLint s0,
                                    GLint s1,
                                    GLint s2,
                                    GLint s3,
-                                   GLint s4,
-                                   GLint s5)
+                                   GLint s4)
  {
-    GLint tokens[6];
+    gl_state_index tokens[STATE_LENGTH];
     GLuint idx;
     tokens[0] = s0;
     tokens[1] = s1;
     tokens[2] = s2;
     tokens[3] = s3;
     tokens[4] = s4;
-    tokens[5] = s5;
     idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens );
     return make_ureg(PROGRAM_STATE_VAR, idx);
  }
  
  
- #define register_param1(p,s0)          register_param6(p,s0,0,0,0,0,0)
- #define register_param2(p,s0,s1)       register_param6(p,s0,s1,0,0,0,0)
- #define register_param3(p,s0,s1,s2)    register_param6(p,s0,s1,s2,0,0,0)
- #define register_param4(p,s0,s1,s2,s3) register_param6(p,s0,s1,s2,s3,0,0)
+ #define register_param1(p,s0)          register_param5(p,s0,0,0,0,0)
+ #define register_param2(p,s0,s1)       register_param5(p,s0,s1,0,0,0)
+ #define register_param3(p,s0,s1,s2)    register_param5(p,s0,s1,s2,0,0)
+ #define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0)
  
  
  static struct ureg register_input( struct texenv_fragment_program *p, GLuint input )
@@@ -523,7 -522,7 +522,7 @@@ static struct ureg emit_arith( struct t
     if (dest.file == PROGRAM_TEMPORARY)
        p->alu_temps |= 1 << dest.idx;
         
-    p->program->NumAluInstructions++;
+    p->program->Base.NumAluInstructions++;
     return dest;
  }
  
@@@ -545,7 -544,7 +544,7 @@@ static struct ureg emit_texld( struct t
     inst->TexSrcTarget = tex_idx;
     inst->TexSrcUnit = tex_unit;
  
-    p->program->NumTexInstructions++;
+    p->program->Base.NumTexInstructions++;
  
     /* Is this a texture indirection?
      */
        (p->temps_output & (1<<coord.idx))) ||
         (dest.file == PROGRAM_TEMPORARY &&
        (p->alu_temps & (1<<dest.idx)))) {
-       p->program->NumTexIndirections++;
+       p->program->Base.NumTexIndirections++;
        p->temps_output = 1<<coord.idx;
        p->alu_temps = 0;
        assert(0);              /* KW: texture env crossbar */
@@@ -570,12 -569,14 +569,14 @@@ static struct ureg register_const4f( st
                                     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);
  }
  
@@@ -1010,10 -1011,10 +1011,10 @@@ create_new_program(GLcontext *ctx, stru
      */
     p.program->Base.Instructions = instBuffer;
     p.program->Base.Target = GL_FRAGMENT_PROGRAM_ARB;
-    p.program->NumTexIndirections = 1; /* correct? */
-    p.program->NumTexInstructions = 0;
-    p.program->NumAluInstructions = 0;
+    p.program->Base.NumTexIndirections = 1;    /* correct? */
+    p.program->Base.NumTexInstructions = 0;
+    p.program->Base.NumAluInstructions = 0;
 -   p.program->Base.String = 0;
 +   p.program->Base.String = NULL;
     p.program->Base.NumInstructions =
     p.program->Base.NumTemporaries =
     p.program->Base.NumParameters =
     } else
        p.program->FogOption = GL_NONE;
  
-    if (p.program->NumTexIndirections > ctx->Const.FragmentProgram.MaxTexIndirections) 
+    if (p.program->Base.NumTexIndirections > ctx->Const.FragmentProgram.MaxTexIndirections) 
        program_error(&p, "Exceeded max nr indirect texture lookups");
  
-    if (p.program->NumTexInstructions > ctx->Const.FragmentProgram.MaxTexInstructions)
+    if (p.program->Base.NumTexInstructions > ctx->Const.FragmentProgram.MaxTexInstructions)
        program_error(&p, "Exceeded max TEX instructions");
  
-    if (p.program->NumAluInstructions > ctx->Const.FragmentProgram.MaxAluInstructions)
+    if (p.program->Base.NumAluInstructions > ctx->Const.FragmentProgram.MaxAluInstructions)
        program_error(&p, "Exceeded max ALU instructions");
  
     ASSERT(p.program->Base.NumInstructions <= MAX_INSTRUCTIONS);
                    "generating tex env program");
        return;
     }
 -   _mesa_memcpy(program->Base.Instructions, instBuffer,
 -                sizeof(struct prog_instruction)
 -                * program->Base.NumInstructions);
 +   _mesa_copy_instructions(program->Base.Instructions, instBuffer,
 +                           program->Base.NumInstructions);
  
     /* Notify driver the fragment program has (actually) changed.
      */
@@@ -1221,32 -1223,49 +1222,49 @@@ static GLuint hash_key( const struct st
     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._Enabled &&
+        !ctx->Shader.CurrentProgram) {
        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._Current =
+          ctx->FragmentProgram._TexEnvProgram =
+             (struct gl_fragment_program *) 
+             ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
  
-        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);
+          create_new_program(ctx, &key, ctx->FragmentProgram._TexEnvProgram);
+          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);
        }
     } 
     else {
      */
     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 b1c148a1367907db5d9eb422105b2441ab06ba8a,8b8bb3a173ac74943d74c637385dff5313a82a6e..63c99ee6ca0fb231453dd9dcd516e61e26824cf1
  #include "glheader.h"
  #include "macros.h"
  #include "enums.h"
+ #include "program.h"
+ #include "prog_instruction.h"
+ #include "prog_parameter.h"
+ #include "prog_print.h"
+ #include "prog_statevars.h"
  #include "t_context.h" /* NOTE: very light dependency on this */
  #include "t_vp_build.h"
  
- #include "shader/program.h"
- #include "shader/program_instruction.h"
  
  struct state_key {
     unsigned light_global_enabled:1;
@@@ -382,11 -385,14 +385,14 @@@ static struct ureg register_const4f( st
  {
     GLfloat values[4];
     GLint idx;
+    GLuint 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);
  }
  
@@@ -408,40 -414,37 +414,37 @@@ static struct ureg get_identity_param( 
     return p->identity;
  }
  
- static struct ureg register_param6( struct tnl_program *p, 
+ static struct ureg register_param5(struct tnl_program *p, 
                                   GLint s0,
                                   GLint s1,
                                   GLint s2,
                                   GLint s3,
-                                  GLint s4,
-                                  GLint s5)
+                                    GLint s4)
  {
-    GLint tokens[6];
+    gl_state_index tokens[STATE_LENGTH];
     GLint idx;
     tokens[0] = s0;
     tokens[1] = s1;
     tokens[2] = s2;
     tokens[3] = s3;
     tokens[4] = s4;
-    tokens[5] = s5;
     idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens );
     return make_ureg(PROGRAM_STATE_VAR, idx);
  }
  
  
- #define register_param1(p,s0)          register_param6(p,s0,0,0,0,0,0)
- #define register_param2(p,s0,s1)       register_param6(p,s0,s1,0,0,0,0)
- #define register_param3(p,s0,s1,s2)    register_param6(p,s0,s1,s2,0,0,0)
- #define register_param4(p,s0,s1,s2,s3) register_param6(p,s0,s1,s2,s3,0,0)
+ #define register_param1(p,s0)          register_param5(p,s0,0,0,0,0)
+ #define register_param2(p,s0,s1)       register_param5(p,s0,s1,0,0,0)
+ #define register_param3(p,s0,s1,s2)    register_param5(p,s0,s1,s2,0,0)
+ #define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0)
  
  
- static void register_matrix_param6( struct tnl_program *p,
-                                   GLint s0,
-                                   GLint s1,
-                                   GLint s2,
-                                   GLint s3,
-                                   GLint s4,
-                                   GLint s5,
+ static void register_matrix_param5( struct tnl_program *p,
+                                   GLint s0, /* modelview, projection, etc */
+                                   GLint s1, /* texture matrix number */
+                                   GLint s2, /* first row */
+                                   GLint s3, /* last row */
+                                   GLint s4, /* inverse, transpose, etc */
                                    struct ureg *matrix )
  {
     GLint i;
     /* This is a bit sad as the support is there to pull the whole
      * matrix out in one go:
      */
-    for (i = 0; i <= s4 - s3; i++) 
-       matrix[i] = register_param6( p, s0, s1, s2, i, i, s5 );
+    for (i = 0; i <= s3 - s2; i++) 
+       matrix[i] = register_param5( p, s0, s1, i, i, s4 );
  }
  
  
@@@ -630,13 -633,13 +633,13 @@@ static struct ureg get_eye_position( st
        p->eye_position = reserve_temp(p);
  
        if (PREFER_DP4) {
-        register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 3, 
-                                STATE_MATRIX, modelview );
+        register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3,
+                                  0, modelview );
  
         emit_matrix_transform_vec4(p, p->eye_position, modelview, pos);
        }
        else {
-        register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 3, 
+        register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3,
                                 STATE_MATRIX_TRANSPOSE, modelview );
  
         emit_transpose_matrix_transform_vec4(p, p->eye_position, modelview, pos);
@@@ -665,7 -668,7 +668,7 @@@ static struct ureg get_eye_normal( stru
        struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL );
        struct ureg mvinv[3];
  
-       register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 2,
+       register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 2,
                              STATE_MATRIX_INVTRANS, mvinv );
  
        p->eye_normal = reserve_temp(p);
@@@ -700,12 -703,12 +703,12 @@@ static void build_hpos( struct tnl_prog
     struct ureg mvp[4];
  
     if (PREFER_DP4) {
-       register_matrix_param6( p, STATE_MATRIX, STATE_MVP, 0, 0, 3, 
-                             STATE_MATRIX, mvp );
+       register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, 
+                             0, mvp );
        emit_matrix_transform_vec4( p, hpos, mvp, pos );
     }
     else {
-       register_matrix_param6( p, STATE_MATRIX, STATE_MVP, 0, 0, 3, 
+       register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, 
                              STATE_MATRIX_TRANSPOSE, mvp );
        emit_transpose_matrix_transform_vec4( p, hpos, mvp, pos );
     }
@@@ -850,7 -853,7 +853,7 @@@ static struct ureg calculate_light_atte
  
  
  /* Need to add some addtional parameters to allow lighting in object
-  * space - STATE_SPOT_DIRECTION and STATE_HALF implicitly assume eye
+  * space - STATE_SPOT_DIRECTION and STATE_HALF_VECTOR implicitly assume eye
   * space lighting.
   */
  static void build_lighting( struct tnl_program *p )
                  emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat);
                  emit_normalize_vec3(p, half, half);
              } else {
-                 half = register_param3(p, STATE_LIGHT, i, STATE_HALF);
+                 half = register_param3(p, STATE_LIGHT, i, STATE_HALF_VECTOR);
              }
         } 
         else {
@@@ -1211,7 -1214,7 +1214,7 @@@ static void build_texture_transform( st
  
     for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
  
-       if (!(p->state->fragprog_inputs_read & (FRAG_BIT_TEX0<<i)))
+       if (!(p->state->fragprog_inputs_read & FRAG_BIT_TEX(i)))
         continue;
                                                             
        if (p->state->unit[i].texgen_enabled || 
                              out_texgen : 
                              register_input(p, VERT_ATTRIB_TEX0+i));
            if (PREFER_DP4) {
-              register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i, 
-                                      0, 3, STATE_MATRIX, texmat );
+              register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3,
+                                      0, texmat );
               emit_matrix_transform_vec4( p, out, texmat, in );
            }
            else {
-              register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i, 
-                                      0, 3, STATE_MATRIX_TRANSPOSE, texmat );
+              register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3,
+                                      STATE_MATRIX_TRANSPOSE, texmat );
               emit_transpose_matrix_transform_vec4( p, out, texmat, in );
            }
         }
@@@ -1416,8 -1419,9 +1419,8 @@@ create_new_program( const struct state_
     else
        p.temp_reserved = ~((1<<max_temps)-1);
  
 -   p.program->Base.Instructions
 -      = (struct prog_instruction*) MALLOC(sizeof(struct prog_instruction) * MAX_INSN);
 -   p.program->Base.String = 0;
 +   p.program->Base.Instructions = _mesa_alloc_instructions(MAX_INSN);
 +   p.program->Base.String = NULL;
     p.program->Base.NumInstructions =
     p.program->Base.NumTemporaries =
     p.program->Base.NumParameters =
@@@ -1503,7 -1507,7 +1506,7 @@@ void _tnl_UpdateFixedFunctionProgram( G
     GLuint hash;
     const struct gl_vertex_program *prev = ctx->VertexProgram._Current;
  
-    if (ctx->VertexProgram._Enabled == GL_FALSE) { 
+    if (!ctx->VertexProgram._Current) {
        /* Grab all the relevent state and put it in a single structure:
         */
        key = make_state_key(ctx);
  
        /* Look for an already-prepared program for this state:
         */
-       ctx->_TnlProgram = (struct gl_vertex_program *)
+       ctx->VertexProgram._TnlProgram = (struct gl_vertex_program *)
         search_cache( tnl->vp_cache, hash, key, sizeof(*key) );
     
        /* OK, we'll have to build a new one:
         */
-       if (!ctx->_TnlProgram) {
+       if (!ctx->VertexProgram._TnlProgram) {
         if (0)
            _mesa_printf("Build new TNL program\n");
         
-        ctx->_TnlProgram = (struct gl_vertex_program *)
+        ctx->VertexProgram._TnlProgram = (struct gl_vertex_program *)
            ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0); 
  
-        create_new_program( key, ctx->_TnlProgram, 
+        create_new_program( key, ctx->VertexProgram._TnlProgram, 
                             ctx->Const.VertexProgram.MaxTemps );
  
         if (ctx->Driver.ProgramStringNotify)
            ctx->Driver.ProgramStringNotify( ctx, GL_VERTEX_PROGRAM_ARB, 
-                                            &ctx->_TnlProgram->Base );
+                                        &ctx->VertexProgram._TnlProgram->Base );
  
-        cache_item(tnl->vp_cache, hash, key, ctx->_TnlProgram );
+        cache_item(tnl->vp_cache, hash, key, ctx->VertexProgram._TnlProgram );
        }
        else {
         FREE(key);
         if (0) 
            _mesa_printf("Found existing TNL program for key %x\n", hash);
        }
-       ctx->VertexProgram._Current = ctx->_TnlProgram;
-    }
-    else {
-       ctx->VertexProgram._Current = ctx->VertexProgram.Current;
+       ctx->VertexProgram._Current = ctx->VertexProgram._TnlProgram;
     }
  
     /* Tell the driver about the change.  Could define a new target for
      * this?
      */
-    if (ctx->VertexProgram._Current != prev &&
-        ctx->Driver.BindProgram) 
+    if (ctx->VertexProgram._Current != prev && ctx->Driver.BindProgram) {
        ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB,
                              (struct gl_program *) ctx->VertexProgram._Current);
+    }
  }
  
  void _tnl_ProgramCacheInit( GLcontext *ctx )