Hi,

this breaks a few things. The patch below gets rid of the assertion failures, but the reference counting needs a proper fix, and swrast draws blackness when ATIfs is enabled.

MM

diff --git a/src/mesa/program/program.c b/src/mesa/program/program.c
index faf5b7fa28..b71917d7b1 100644
--- a/src/mesa/program/program.c
+++ b/src/mesa/program/program.c
@@ -258,7 +258,6 @@ _mesa_delete_program(struct gl_context *ctx, struct gl_program *prog)
 {
    (void) ctx;
    assert(prog);
-   assert(prog->RefCount==0);

    if (prog == &_mesa_DummyProgram)
       return;
@@ -320,7 +319,8 @@ _mesa_reference_program_(struct gl_context *ctx,
          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);
+                prog->Target == GL_FRAGMENT_PROGRAM_NV ||
+                prog->Target == GL_FRAGMENT_SHADER_ATI);
       else if ((*ptr)->Target == GL_GEOMETRY_PROGRAM_NV)
          assert(prog->Target == GL_GEOMETRY_PROGRAM_NV);
    }
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index e3649a8b7c..fe0724d331 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -1843,6 +1843,7 @@ destroy_program_variants(struct st_context *st, struct gl_program *target)
          }
       }
       break;
+   case GL_FRAGMENT_SHADER_ATI:
    case GL_FRAGMENT_PROGRAM_ARB:
       {
          struct st_fragment_program *stfp =
@@ -2029,6 +2030,7 @@ st_precompile_shader_variant(struct st_context *st,
       break;
    }

+   case GL_FRAGMENT_SHADER_ATI:
    case GL_FRAGMENT_PROGRAM_ARB: {
       struct st_fragment_program *p = (struct st_fragment_program *)prog;
       struct st_fp_variant_key key;
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c
index 9f3d21f91d..b8160509c7 100644
--- a/src/mesa/swrast/s_context.c
+++ b/src/mesa/swrast/s_context.c
@@ -251,7 +251,7 @@ _swrast_update_fog_state( struct gl_context *ctx )
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    const struct gl_program *fp = ctx->FragmentProgram._Current;

-   assert(fp == NULL || fp->Target == GL_FRAGMENT_PROGRAM_ARB);
+   assert(fp == NULL || fp->Target == GL_FRAGMENT_PROGRAM_ARB || fp->Target == GL_FRAGMENT_SHADER_ATI);
    (void) fp; /* silence unused var warning */

    /* determine if fog is needed, and if so, which fog mode */


On 10/11/17 11:35, Timothy Arceri wrote:
This increases the size of gl_program but in future a union
can be used to offset this increase in memory use. Combining
the two reduces code and make it easier to follow.

Cc: Miklós Máté <mtm...@gmail.com>
---

  NOTE: compile tested only.

  src/mesa/drivers/common/driverfuncs.c       |   3 -
  src/mesa/drivers/dri/r200/r200_context.h    |   2 +-
  src/mesa/drivers/dri/r200/r200_fragshader.c |  86 ++++++-------
  src/mesa/drivers/dri/r200/r200_state_init.c |   2 +-
  src/mesa/drivers/dri/r200/r200_vertprog.c   |   1 +
  src/mesa/main/atifragshader.c               | 193 +++++++++++++---------------
  src/mesa/main/atifragshader.h               |   4 +-
  src/mesa/main/dd.h                          |   6 +-
  src/mesa/main/mtypes.h                      |  57 ++++----
  src/mesa/main/shared.c                      |   2 +-
  src/mesa/main/state.c                       |   4 +-
  src/mesa/main/state.h                       |   2 +-
  src/mesa/program/program.c                  |   3 +-
  src/mesa/state_tracker/st_atifs_to_tgsi.c   |  28 ++--
  src/mesa/state_tracker/st_atifs_to_tgsi.h   |   2 -
  src/mesa/state_tracker/st_atom_constbuf.c   |   9 +-
  src/mesa/state_tracker/st_atom_shader.c     |   8 +-
  src/mesa/state_tracker/st_cb_program.c      |  20 +--
  src/mesa/state_tracker/st_program.c         |   7 +-
  src/mesa/state_tracker/st_program.h         |   1 -
  src/mesa/swrast/s_atifragshader.c           |  18 +--
  21 files changed, 206 insertions(+), 252 deletions(-)

diff --git a/src/mesa/drivers/common/driverfuncs.c 
b/src/mesa/drivers/common/driverfuncs.c
index ddb4bb6d6a..a8b4d9857f 100644
--- a/src/mesa/drivers/common/driverfuncs.c
+++ b/src/mesa/drivers/common/driverfuncs.c
@@ -110,23 +110,20 @@ _mesa_init_driver_functions(struct dd_function_table 
*driver)
     driver->AllocTextureImageBuffer = _swrast_alloc_texture_image_buffer;
     driver->FreeTextureImageBuffer = _swrast_free_texture_image_buffer;
     driver->MapTextureImage = _swrast_map_teximage;
     driver->UnmapTextureImage = _swrast_unmap_teximage;
     driver->DrawTex = _mesa_meta_DrawTex;
/* Vertex/fragment programs */
     driver->NewProgram = _mesa_new_program;
     driver->DeleteProgram = _mesa_delete_program;
- /* ATI_fragment_shader */
-   driver->NewATIfs = NULL;
-
     /* simple state commands */
     driver->AlphaFunc = NULL;
     driver->BlendColor = NULL;
     driver->BlendEquationSeparate = NULL;
     driver->BlendFuncSeparate = NULL;
     driver->ClipPlane = NULL;
     driver->ColorMask = NULL;
     driver->ColorMaterial = NULL;
     driver->CullFace = NULL;
     driver->DrawBuffer = NULL;
diff --git a/src/mesa/drivers/dri/r200/r200_context.h 
b/src/mesa/drivers/dri/r200/r200_context.h
index f9ba6835e8..e164c5d186 100644
--- a/src/mesa/drivers/dri/r200/r200_context.h
+++ b/src/mesa/drivers/dri/r200/r200_context.h
@@ -606,21 +606,21 @@ struct r200_context {
     /* r200_tcl.c
      */
     struct r200_tcl_info tcl;
/* r200_swtcl.c
      */
     struct r200_swtcl_info swtcl;
GLboolean using_hyperz; - struct ati_fragment_shader *afs_loaded;
+  struct gl_program *afs_loaded;
  };
static inline r200ContextPtr
  R200_CONTEXT(struct gl_context *ctx)
  {
     return (r200ContextPtr) ctx;
  }
diff --git a/src/mesa/drivers/dri/r200/r200_fragshader.c b/src/mesa/drivers/dri/r200/r200_fragshader.c
index ca772f1c87..1eb9c7e4ec 100644
--- a/src/mesa/drivers/dri/r200/r200_fragshader.c
+++ b/src/mesa/drivers/dri/r200/r200_fragshader.c
@@ -118,38 +118,38 @@ static GLuint dstmask_table[8] =
     R200_TXC_OUTPUT_MASK_B,
     R200_TXC_OUTPUT_MASK_RB,
     R200_TXC_OUTPUT_MASK_GB,
     R200_TXC_OUTPUT_MASK_RGB
  };
static void r200UpdateFSArith( struct gl_context *ctx )
  {
     r200ContextPtr rmesa = R200_CONTEXT(ctx);
     GLuint *afs_cmd;
-   const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current;
+   const struct gl_program *shader = ctx->ATIFragmentShader.Current;
     GLuint pass;
R200_STATECHANGE( rmesa, afs[0] );
     R200_STATECHANGE( rmesa, afs[1] );
- if (shader->NumPasses < 2) {
+   if (shader->ati.NumPasses < 2) {
        afs_cmd = (GLuint *) rmesa->hw.afs[1].cmd;
     }
     else {
        afs_cmd = (GLuint *) rmesa->hw.afs[0].cmd;
     }
-   for (pass = 0; pass < shader->NumPasses; pass++) {
+   for (pass = 0; pass < shader->ati.NumPasses; pass++) {
        GLuint opnum = 0;
        GLuint pc;
-      for (pc = 0; pc < shader->numArithInstr[pass]; pc++) {
+      for (pc = 0; pc < shader->ati.numArithInstr[pass]; pc++) {
           GLuint optype;
-        struct atifs_instruction *inst = &shader->Instructions[pass][pc];
+        struct atifs_instruction *inst = &shader->ati.Instructions[pass][pc];
SET_INST(opnum, 0) = 0;
         SET_INST_2(opnum, 0) = 0;
         SET_INST(opnum, 1) = 0;
         SET_INST_2(opnum, 1) = 0;
for (optype = 0; optype < 2; optype++) {
            GLuint tfactor = 0;
if (inst->Opcode[optype]) {
@@ -274,22 +274,22 @@ static void r200UpdateFSArith( struct gl_context *ctx )
               GLuint dstmod = inst->DstReg[optype].dstMod;
dstmod &= ~GL_SATURATE_BIT_ATI; SET_INST_2(opnum, optype) |= (dstreg + 1) << R200_TXC_OUTPUT_REG_SHIFT;
               SET_INST_2(opnum, optype) |= dstmask_table[dstmask];
/* fglrx does clamp the last instructions to 0_1 it seems */
                /* this won't necessarily catch the last instruction
                   which writes to reg0 */
-              if (sat || (pc == (shader->numArithInstr[pass] - 1) &&
-                       ((pass == 1) || (shader->NumPasses == 1))))
+              if (sat || (pc == (shader->ati.numArithInstr[pass] - 1) &&
+                       ((pass == 1) || (shader->ati.NumPasses == 1))))
                  SET_INST_2(opnum, optype) |= R200_TXC_CLAMP_0_1;
               else
                /*should we clamp or not? spec is vague, I would suppose yes 
but fglrx doesn't */
                  SET_INST_2(opnum, optype) |= R200_TXC_CLAMP_8_8;
  /*              SET_INST_2(opnum, optype) |= R200_TXC_CLAMP_WRAP;*/
               switch(dstmod) {
               case GL_2X_BIT_ATI:
                  SET_INST_2(opnum, optype) |= R200_TXC_SCALE_2X;
                  break;
               case GL_4X_BIT_ATI:
@@ -317,172 +317,172 @@ static void r200UpdateFSArith( struct gl_context *ctx )
                SET_INST(opnum, 1), SET_INST_2(opnum, 1));*/
           opnum++;
        }
        afs_cmd = (GLuint *) rmesa->hw.afs[1].cmd;
     }
     rmesa->afs_loaded = ctx->ATIFragmentShader.Current;
  }
static void r200UpdateFSRouting( struct gl_context *ctx ) {
     r200ContextPtr rmesa = R200_CONTEXT(ctx);
-   const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current;
+   const struct gl_program *shader = ctx->ATIFragmentShader.Current;
     GLuint reg;
R200_STATECHANGE( rmesa, ctx );
     R200_STATECHANGE( rmesa, cst );
for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) {
-      if (shader->swizzlerq & (1 << (2 * reg)))
+      if (shader->ati.swizzlerq & (1 << (2 * reg)))
         /* r coord */
         set_re_cntl_d3d( ctx, reg, 1);
         /* q coord */
        else set_re_cntl_d3d( ctx, reg, 0);
     }
rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_MULTI_PASS_ENABLE |
                                       R200_TEX_BLEND_ENABLE_MASK |
                                       R200_TEX_ENABLE_MASK);
     rmesa->hw.cst.cmd[CST_PP_CNTL_X] &= ~(R200_PPX_PFS_INST_ENABLE_MASK |
                                         R200_PPX_TEX_ENABLE_MASK |
                                         R200_PPX_OUTPUT_REG_MASK);
/* first pass registers use slots 8 - 15
        but single pass shaders use slots 0 - 7 */
-   if (shader->NumPasses < 2) {
-      rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= shader->numArithInstr[0] == 8 ?
+   if (shader->ati.NumPasses < 2) {
+      rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= shader->ati.numArithInstr[0] == 8 ?
         0xff << (R200_TEX_BLEND_0_ENABLE_SHIFT - 1) :
-        (0xff >> (8 - shader->numArithInstr[0])) << 
R200_TEX_BLEND_0_ENABLE_SHIFT;
+        (0xff >> (8 - shader->ati.numArithInstr[0])) << 
R200_TEX_BLEND_0_ENABLE_SHIFT;
     } else {
        rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_MULTI_PASS_ENABLE;
-      rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= shader->numArithInstr[1] == 8 ?
+      rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= shader->ati.numArithInstr[1] == 8 ?
         0xff << (R200_TEX_BLEND_0_ENABLE_SHIFT - 1) :
-        (0xff >> (8 - shader->numArithInstr[1])) << 
R200_TEX_BLEND_0_ENABLE_SHIFT;
+        (0xff >> (8 - shader->ati.numArithInstr[1])) << 
R200_TEX_BLEND_0_ENABLE_SHIFT;
        rmesa->hw.cst.cmd[CST_PP_CNTL_X] |=
-        (0xff >> (8 - shader->numArithInstr[0])) << 
R200_PPX_FPS_INST0_ENABLE_SHIFT;
+        (0xff >> (8 - shader->ati.numArithInstr[0])) << 
R200_PPX_FPS_INST0_ENABLE_SHIFT;
     }
- if (shader->NumPasses < 2) {
+   if (shader->ati.NumPasses < 2) {
        for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) {
           struct gl_texture_object *texObj = ctx->Texture.Unit[reg]._Current;
           R200_STATECHANGE( rmesa, tex[reg] );
         rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = 0;
-        if (shader->SetupInst[0][reg].Opcode) {
+        if (shader->ati.SetupInst[0][reg].Opcode) {
            GLuint txformat = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT]
                & ~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);
            GLuint txformat_x = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] & 
~R200_TEXCOORD_MASK;
-           txformat |= (shader->SetupInst[0][reg].src - GL_TEXTURE0_ARB)
+           txformat |= (shader->ati.SetupInst[0][reg].src - GL_TEXTURE0_ARB)
                << R200_TXFORMAT_ST_ROUTE_SHIFT;
            /* fix up texcoords for proj/non-proj 2d (3d and cube are not 
defined when
               using projection so don't have to worry there).
               When passing coords, need R200_TEXCOORD_VOLUME, otherwise loose 
a coord */
            /* FIXME: someone might rely on default tex coords r/q, which we 
unfortunately
               don't provide (we have the same problem without shaders) */
-           if (shader->SetupInst[0][reg].Opcode == 
ATI_FRAGMENT_SHADER_PASS_OP) {
+           if (shader->ati.SetupInst[0][reg].Opcode == 
ATI_FRAGMENT_SHADER_PASS_OP) {
               txformat |= R200_TXFORMAT_LOOKUP_DISABLE;
-              if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||
-                 shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
+              if (shader->ati.SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI 
||
+                 shader->ati.SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
                  txformat_x |= R200_TEXCOORD_VOLUME;
               }
               else {
                  txformat_x |= R200_TEXCOORD_PROJ;
               }
               rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
            }
            else if (texObj && texObj->Target == GL_TEXTURE_3D) {
               txformat_x |= R200_TEXCOORD_VOLUME;
            }
            else if (texObj && texObj->Target == GL_TEXTURE_CUBE_MAP) {
               txformat_x |= R200_TEXCOORD_CUBIC_ENV;
            }
-           else if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||
-              shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
+           else if (shader->ati.SetupInst[0][reg].swizzle == 
GL_SWIZZLE_STR_ATI ||
+              shader->ati.SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
               txformat_x |= R200_TEXCOORD_NONPROJ;
            }
            else {
               txformat_x |= R200_TEXCOORD_PROJ;
            }
            rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT] = txformat;
            rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] = txformat_x;
            /* enabling texturing when unit isn't correctly configured may not 
be safe */
            if (texObj)
               rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
         }
        }
} else {
        /* setup 1st pass */
        for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) {
         struct gl_texture_object *texObj = ctx->Texture.Unit[reg]._Current;
         R200_STATECHANGE( rmesa, tex[reg] );
         GLuint txformat_multi = 0;
-        if (shader->SetupInst[0][reg].Opcode) {
-           txformat_multi |= (shader->SetupInst[0][reg].src - GL_TEXTURE0_ARB)
+        if (shader->ati.SetupInst[0][reg].Opcode) {
+           txformat_multi |= (shader->ati.SetupInst[0][reg].src - 
GL_TEXTURE0_ARB)
                << R200_PASS1_ST_ROUTE_SHIFT;
-           if (shader->SetupInst[0][reg].Opcode == 
ATI_FRAGMENT_SHADER_PASS_OP) {
+           if (shader->ati.SetupInst[0][reg].Opcode == 
ATI_FRAGMENT_SHADER_PASS_OP) {
               txformat_multi |= R200_PASS1_TXFORMAT_LOOKUP_DISABLE;
-              if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||
-                 shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
+              if (shader->ati.SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI 
||
+                 shader->ati.SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
                  txformat_multi |= R200_PASS1_TEXCOORD_VOLUME;
               }
               else {
                  txformat_multi |= R200_PASS1_TEXCOORD_PROJ;
               }
               rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_0_ENABLE << reg;
            }
            else if (texObj && texObj->Target == GL_TEXTURE_3D) {
               txformat_multi |= R200_PASS1_TEXCOORD_VOLUME;
            }
            else if (texObj && texObj->Target == GL_TEXTURE_CUBE_MAP) {
               txformat_multi |= R200_PASS1_TEXCOORD_CUBIC_ENV;
            }
-           else if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||
-                 shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
+           else if (shader->ati.SetupInst[0][reg].swizzle == 
GL_SWIZZLE_STR_ATI ||
+                 shader->ati.SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
                  txformat_multi |= R200_PASS1_TEXCOORD_NONPROJ;
            }
            else {
               txformat_multi |= R200_PASS1_TEXCOORD_PROJ;
            }
            if (texObj)
               rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_0_ENABLE << reg;
         }
           rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = txformat_multi;
        }
/* setup 2nd pass */
        for (reg=0; reg < R200_MAX_TEXTURE_UNITS; reg++) {
         struct gl_texture_object *texObj = ctx->Texture.Unit[reg]._Current;
-        if (shader->SetupInst[1][reg].Opcode) {
-           GLuint coord = shader->SetupInst[1][reg].src;
+        if (shader->ati.SetupInst[1][reg].Opcode) {
+           GLuint coord = shader->ati.SetupInst[1][reg].src;
            GLuint txformat = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT]
                & ~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);
            GLuint txformat_x = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] & 
~R200_TEXCOORD_MASK;
            R200_STATECHANGE( rmesa, tex[reg] );
-           if (shader->SetupInst[1][reg].Opcode == 
ATI_FRAGMENT_SHADER_PASS_OP) {
+           if (shader->ati.SetupInst[1][reg].Opcode == 
ATI_FRAGMENT_SHADER_PASS_OP) {
               txformat |= R200_TXFORMAT_LOOKUP_DISABLE;
               txformat_x |= R200_TEXCOORD_VOLUME;
-              if (shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STR_ATI ||
-                 shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
+              if (shader->ati.SetupInst[1][reg].swizzle == GL_SWIZZLE_STR_ATI 
||
+                 shader->ati.SetupInst[1][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
                  txformat_x |= R200_TEXCOORD_VOLUME;
               }
               else {
                  txformat_x |= R200_TEXCOORD_PROJ;
               }
               rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
            }
            else if (texObj && texObj->Target == GL_TEXTURE_3D) {
               txformat_x |= R200_TEXCOORD_VOLUME;
            }
            else if (texObj && texObj->Target == GL_TEXTURE_CUBE_MAP) {
               txformat_x |= R200_TEXCOORD_CUBIC_ENV;
            }
-           else if (shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STR_ATI ||
-              shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
+           else if (shader->ati.SetupInst[1][reg].swizzle == 
GL_SWIZZLE_STR_ATI ||
+              shader->ati.SetupInst[1][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
               txformat_x |= R200_TEXCOORD_NONPROJ;
            }
            else {
               txformat_x |= R200_TEXCOORD_PROJ;
            }
            if (coord >= GL_REG_0_ATI) {
               GLuint txformat_multi = 
rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL];
               txformat_multi |= (coord - GL_REG_0_ATI + 2) << 
R200_PASS2_COORDS_REG_SHIFT;
               rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = txformat_multi;
               rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= 1 <<
@@ -495,33 +495,33 @@ static void r200UpdateFSRouting( struct gl_context *ctx ) 
{
            if (texObj)
               rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
         }
        }
     }
  }
static void r200UpdateFSConstants( struct gl_context *ctx )
  {
     r200ContextPtr rmesa = R200_CONTEXT(ctx);
-   const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current;
+   const struct gl_program *shader = ctx->ATIFragmentShader.Current;
     GLuint i;
/* update constants */
     R200_STATECHANGE(rmesa, atf);
     for (i = 0; i < 8; i++)
     {
        GLubyte con_byte[4];
-      if ((shader->LocalConstDef >> i) & 1) {
-        CLAMPED_FLOAT_TO_UBYTE(con_byte[0], shader->Constants[i][0]);
-        CLAMPED_FLOAT_TO_UBYTE(con_byte[1], shader->Constants[i][1]);
-        CLAMPED_FLOAT_TO_UBYTE(con_byte[2], shader->Constants[i][2]);
-        CLAMPED_FLOAT_TO_UBYTE(con_byte[3], shader->Constants[i][3]);
+      if ((shader->ati.LocalConstDef >> i) & 1) {
+        CLAMPED_FLOAT_TO_UBYTE(con_byte[0], shader->ati.Constants[i][0]);
+        CLAMPED_FLOAT_TO_UBYTE(con_byte[1], shader->ati.Constants[i][1]);
+        CLAMPED_FLOAT_TO_UBYTE(con_byte[2], shader->ati.Constants[i][2]);
+        CLAMPED_FLOAT_TO_UBYTE(con_byte[3], shader->ati.Constants[i][3]);
        }
        else {
         CLAMPED_FLOAT_TO_UBYTE(con_byte[0], 
ctx->ATIFragmentShader.GlobalConstants[i][0]);
         CLAMPED_FLOAT_TO_UBYTE(con_byte[1], 
ctx->ATIFragmentShader.GlobalConstants[i][1]);
         CLAMPED_FLOAT_TO_UBYTE(con_byte[2], 
ctx->ATIFragmentShader.GlobalConstants[i][2]);
         CLAMPED_FLOAT_TO_UBYTE(con_byte[3], 
ctx->ATIFragmentShader.GlobalConstants[i][3]);
        }
        rmesa->hw.atf.cmd[ATF_TFACTOR_0 + i] = radeonPackColor (
         4, con_byte[0], con_byte[1], con_byte[2], con_byte[3] );
     }
diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c 
b/src/mesa/drivers/dri/r200/r200_state_init.c
index 4b589cd8b8..48ac7f4fd1 100644
--- a/src/mesa/drivers/dri/r200/r200_state_init.c
+++ b/src/mesa/drivers/dri/r200/r200_state_init.c
@@ -248,21 +248,21 @@ static int check_##NM( struct gl_context *ctx, struct 
radeon_state_atom *atom )
     return (!rmesa->radeon.TclFallback && _mesa_arb_vertex_program_enabled(ctx) 
&& (FLAG)) ? atom->cmd_size + (ADD) : 0; \
  }
CHECK( always, GL_TRUE, 0 )
  CHECK( always_add4, GL_TRUE, 4 )
  CHECK( never, GL_FALSE, 0 )
  CHECK( tex_any, ctx->Texture._MaxEnabledTexImageUnit != -1, 0 )
  CHECK( tf, (ctx->Texture._MaxEnabledTexImageUnit != -1 && 
!_mesa_ati_fragment_shader_enabled(ctx)), 0 );
  CHECK( pix_zero, !_mesa_ati_fragment_shader_enabled(ctx), 0 )
  CHECK( texenv, (rmesa->state.envneeded & (1 << (atom->idx)) && 
!_mesa_ati_fragment_shader_enabled(ctx)), 0 )
-CHECK( afs_pass1, (_mesa_ati_fragment_shader_enabled(ctx) && 
(ctx->ATIFragmentShader.Current->NumPasses > 1)), 0 )
+CHECK( afs_pass1, (_mesa_ati_fragment_shader_enabled(ctx) && 
(ctx->ATIFragmentShader.Current->ati.NumPasses > 1)), 0 )
  CHECK( afs, _mesa_ati_fragment_shader_enabled(ctx), 0 )
  CHECK( tex_cube, rmesa->state.texture.unit[atom->idx].unitneeded & 
TEXTURE_CUBE_BIT, 3 + 3*5 - CUBE_STATE_SIZE )
  CHECK( tex_cube_cs, rmesa->state.texture.unit[atom->idx].unitneeded & 
TEXTURE_CUBE_BIT, 2 + 4*5 - CUBE_STATE_SIZE )
  TCL_CHECK( tcl_fog_add4, ctx->Fog.Enabled, 4 )
  TCL_CHECK( tcl, GL_TRUE, 0 )
  TCL_CHECK( tcl_add8, GL_TRUE, 8 )
  TCL_CHECK( tcl_add4, GL_TRUE, 4 )
  TCL_CHECK( tcl_tex_add4, rmesa->state.texture.unit[atom->idx].unitneeded, 4 )
  TCL_CHECK( tcl_lighting_add4, ctx->Light.Enabled, 4 )
  TCL_CHECK( tcl_lighting_add6, ctx->Light.Enabled, 6 )
diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c 
b/src/mesa/drivers/dri/r200/r200_vertprog.c
index bb8550332b..1340fd0a3c 100644
--- a/src/mesa/drivers/dri/r200/r200_vertprog.c
+++ b/src/mesa/drivers/dri/r200/r200_vertprog.c
@@ -1186,20 +1186,21 @@ void r200SetupVertexProg( struct gl_context *ctx ) {
  static struct gl_program *
  r200NewProgram(struct gl_context *ctx, GLenum target, GLuint id,
                 bool is_arb_asm)
  {
     switch(target){
     case GL_VERTEX_PROGRAM_ARB: {
        struct r200_vertex_program *vp = rzalloc(NULL,
                                                 struct r200_vertex_program);
        return _mesa_init_gl_program(&vp->mesa_program, target, id, is_arb_asm);
     }
+   case GL_FRAGMENT_SHADER_ATI:
     case GL_FRAGMENT_PROGRAM_ARB: {
        struct gl_program *prog = rzalloc(NULL, struct gl_program);
        return _mesa_init_gl_program(prog, target, id, is_arb_asm);
     }
     default:
        _mesa_problem(ctx, "Bad target in r200NewProgram");
        return NULL;
     }
  }
diff --git a/src/mesa/main/atifragshader.c b/src/mesa/main/atifragshader.c
index 49ddb6e5af..b0b2f93d65 100644
--- a/src/mesa/main/atifragshader.c
+++ b/src/mesa/main/atifragshader.c
@@ -27,78 +27,71 @@
  #include "main/imports.h"
  #include "main/macros.h"
  #include "main/enums.h"
  #include "main/mtypes.h"
  #include "main/dispatch.h"
  #include "main/atifragshader.h"
  #include "program/program.h"
#define MESA_DEBUG_ATI_FS 0 -static struct ati_fragment_shader DummyShader;
+static struct gl_program DummyShader;
/**
   * Allocate and initialize a new ATI fragment shader object.
   */
-struct ati_fragment_shader *
+struct gl_program *
  _mesa_new_ati_fragment_shader(struct gl_context *ctx, GLuint id)
  {
-   struct ati_fragment_shader *s = CALLOC_STRUCT(ati_fragment_shader);
-   (void) ctx;
-   if (s) {
-      s->Id = id;
-      s->RefCount = 1;
-   }
-   return s;
+   return ctx->Driver.NewProgram(ctx, GL_FRAGMENT_SHADER_ATI, id, true);
  }
/**
   * Delete the given ati fragment shader
   */
  void
-_mesa_delete_ati_fragment_shader(struct gl_context *ctx, struct 
ati_fragment_shader *s)
+_mesa_delete_ati_fragment_shader(struct gl_context *ctx, struct gl_program *s)
  {
     GLuint i;
if (s == &DummyShader)
        return;
for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {
-      free(s->Instructions[i]);
-      free(s->SetupInst[i]);
+      free(s->ati.Instructions[i]);
+      free(s->ati.SetupInst[i]);
     }
-   _mesa_reference_program(ctx, &s->Program, NULL);
-   free(s);
+   ctx->Driver.DeleteProgram(ctx, s);
  }
static void
-new_arith_inst(struct ati_fragment_shader *prog)
+new_arith_inst(struct gl_program *prog)
  {
  /* set "default" instruction as not all may get defined.
     there is no specified way to express a nop with ati fragment shaders we use
     GL_NONE as the op enum and just set some params to 0 - so nothing to do 
here */
-   prog->numArithInstr[prog->cur_pass >> 1]++;
+   prog->ati.numArithInstr[prog->ati.cur_pass >> 1]++;
  }
static void
-new_tex_inst(struct ati_fragment_shader *prog)
+new_tex_inst(struct gl_program *prog)
  {
  }
-static void match_pair_inst(struct ati_fragment_shader *curProg, GLuint optype)
+static void match_pair_inst(struct gl_program *curProg, GLuint optype)
  {
-   if (optype == curProg->last_optype) {
-      curProg->last_optype = 1;
+   if (optype == curProg->ati.last_optype) {
+      curProg->ati.last_optype = 1;
     }
  }
#if MESA_DEBUG_ATI_FS
  static char *
  create_dst_mod_str(GLuint mod)
  {
     static char ret_str[1024];
memset(ret_str, 0, 1024);
@@ -152,21 +145,21 @@ static void debug_op(GLint optype, GLuint arg_count, 
GLenum op, GLuint dst,
              _mesa_enum_to_string(arg2Rep), arg2Mod);
    if (arg_count>2)
      fprintf(stderr, ", %s, %s, %d", _mesa_enum_to_string(arg3),
              _mesa_enum_to_string(arg3Rep), arg3Mod);
fprintf(stderr,")\n"); }
  #endif
-static int check_arith_arg(struct ati_fragment_shader *curProg,
+static int check_arith_arg(struct gl_program *curProg,
                        GLuint optype, GLuint arg, GLuint argRep)
  {
     GET_CURRENT_CONTEXT(ctx);
if (((arg < GL_CON_0_ATI) || (arg > GL_CON_7_ATI)) &&
        ((arg < GL_REG_0_ATI) || (arg > GL_REG_5_ATI)) &&
        (arg != GL_ZERO) && (arg != GL_ONE) &&
        (arg != GL_PRIMARY_COLOR_ARB) && (arg != 
GL_SECONDARY_INTERPOLATOR_ATI)) {
        _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(arg)");
        return 0;
@@ -174,23 +167,23 @@ static int check_arith_arg(struct ati_fragment_shader 
*curProg,
     if ((arg == GL_SECONDARY_INTERPOLATOR_ATI) && (((optype == 0) && (argRep 
== GL_ALPHA)) ||
        ((optype == 1) && ((arg == GL_ALPHA) || (argRep == GL_NONE))))) {
        _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)");
        return 0;
     }
     if ((arg == GL_SECONDARY_INTERPOLATOR_ATI) && (((optype == 0) && (argRep 
== GL_ALPHA)) ||
        ((optype == 1) && ((arg == GL_ALPHA) || (argRep == GL_NONE))))) {
        _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)");
        return 0;
     }
-   if ((curProg->cur_pass == 1) &&
+   if ((curProg->ati.cur_pass == 1) &&
        ((arg == GL_PRIMARY_COLOR_ARB) || (arg == 
GL_SECONDARY_INTERPOLATOR_ATI))) {
-      curProg->interpinp1 = GL_TRUE;
+      curProg->ati.interpinp1 = GL_TRUE;
     }
     return 1;
  }
GLuint GLAPIENTRY
  _mesa_GenFragmentShadersATI(GLuint range)
  {
     GLuint first;
     GLuint i;
     GET_CURRENT_CONTEXT(ctx);
@@ -214,22 +207,22 @@ _mesa_GenFragmentShadersATI(GLuint range)
_mesa_HashUnlockMutex(ctx->Shared->ATIShaders); return first;
  }
void GLAPIENTRY
  _mesa_BindFragmentShaderATI(GLuint id)
  {
     GET_CURRENT_CONTEXT(ctx);
-   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
-   struct ati_fragment_shader *newProg;
+   struct gl_program *curProg = ctx->ATIFragmentShader.Current;
+   struct gl_program *newProg;
if (ctx->ATIFragmentShader.Compiling) {
        _mesa_error(ctx, GL_INVALID_OPERATION, 
"glBindFragmentShaderATI(insideShader)");
        return;
     }
FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (curProg->Id == id) {
        return;
@@ -241,21 +234,21 @@ _mesa_BindFragmentShaderATI(GLuint id)
        if (curProg->RefCount <= 0) {
         _mesa_HashRemove(ctx->Shared->ATIShaders, id);
        }
     }
/* find new shader */
     if (id == 0) {
        newProg = ctx->Shared->DefaultFragmentShader;
     }
     else {
-      newProg = (struct ati_fragment_shader *)
+      newProg = (struct gl_program *)
           _mesa_HashLookup(ctx->Shared->ATIShaders, id);
        if (!newProg || newProg == &DummyShader) {
         /* allocate a new program now */
         newProg = _mesa_new_ati_fragment_shader(ctx, id);
         if (!newProg) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFragmentShaderATI");
            return;
         }
         _mesa_HashInsert(ctx->Shared->ATIShaders, id, newProg);
        }
@@ -274,21 +267,21 @@ void GLAPIENTRY
  _mesa_DeleteFragmentShaderATI(GLuint id)
  {
     GET_CURRENT_CONTEXT(ctx);
if (ctx->ATIFragmentShader.Compiling) {
        _mesa_error(ctx, GL_INVALID_OPERATION, 
"glDeleteFragmentShaderATI(insideShader)");
        return;
     }
if (id != 0) {
-      struct ati_fragment_shader *prog = (struct ati_fragment_shader *)
+      struct gl_program *prog = (struct gl_program *)
         _mesa_HashLookup(ctx->Shared->ATIShaders, id);
        if (prog == &DummyShader) {
         _mesa_HashRemove(ctx->Shared->ATIShaders, id);
        }
        else if (prog) {
         if (ctx->ATIFragmentShader.Current &&
             ctx->ATIFragmentShader.Current->Id == id) {
             FLUSH_VERTICES(ctx, _NEW_PROGRAM);
            _mesa_BindFragmentShaderATI(0);
         }
@@ -316,310 +309,302 @@ _mesa_BeginFragmentShaderATI(void)
        _mesa_error(ctx, GL_INVALID_OPERATION, 
"glBeginFragmentShaderATI(insideShader)");
        return;
     }
FLUSH_VERTICES(ctx, _NEW_PROGRAM); /* if the shader was already defined free instructions and get new ones
        (or, could use the same mem but would need to reinitialize) */
     /* no idea if it's allowed to redefine a shader */
     for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {
-         free(ctx->ATIFragmentShader.Current->Instructions[i]);
-         free(ctx->ATIFragmentShader.Current->SetupInst[i]);
+         free(ctx->ATIFragmentShader.Current->ati.Instructions[i]);
+         free(ctx->ATIFragmentShader.Current->ati.SetupInst[i]);
     }
- _mesa_reference_program(ctx, &ctx->ATIFragmentShader.Current->Program, NULL);
-
     /* malloc the instructions here - not sure if the best place but its
        a start */
     for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {
-      ctx->ATIFragmentShader.Current->Instructions[i] =
+      ctx->ATIFragmentShader.Current->ati.Instructions[i] =
         calloc(sizeof(struct atifs_instruction),
                  MAX_NUM_INSTRUCTIONS_PER_PASS_ATI);
-      ctx->ATIFragmentShader.Current->SetupInst[i] =
+      ctx->ATIFragmentShader.Current->ati.SetupInst[i] =
         calloc(sizeof(struct atifs_setupinst),
                  MAX_NUM_FRAGMENT_REGISTERS_ATI);
     }
/* can't rely on calloc for initialization as it's possible to redefine a shader (?) */
-   ctx->ATIFragmentShader.Current->LocalConstDef = 0;
-   ctx->ATIFragmentShader.Current->numArithInstr[0] = 0;
-   ctx->ATIFragmentShader.Current->numArithInstr[1] = 0;
-   ctx->ATIFragmentShader.Current->regsAssigned[0] = 0;
-   ctx->ATIFragmentShader.Current->regsAssigned[1] = 0;
-   ctx->ATIFragmentShader.Current->NumPasses = 0;
-   ctx->ATIFragmentShader.Current->cur_pass = 0;
-   ctx->ATIFragmentShader.Current->last_optype = 0;
-   ctx->ATIFragmentShader.Current->interpinp1 = GL_FALSE;
-   ctx->ATIFragmentShader.Current->isValid = GL_FALSE;
-   ctx->ATIFragmentShader.Current->swizzlerq = 0;
+   ctx->ATIFragmentShader.Current->ati.LocalConstDef = 0;
+   ctx->ATIFragmentShader.Current->ati.numArithInstr[0] = 0;
+   ctx->ATIFragmentShader.Current->ati.numArithInstr[1] = 0;
+   ctx->ATIFragmentShader.Current->ati.regsAssigned[0] = 0;
+   ctx->ATIFragmentShader.Current->ati.regsAssigned[1] = 0;
+   ctx->ATIFragmentShader.Current->ati.NumPasses = 0;
+   ctx->ATIFragmentShader.Current->ati.cur_pass = 0;
+   ctx->ATIFragmentShader.Current->ati.last_optype = 0;
+   ctx->ATIFragmentShader.Current->ati.interpinp1 = GL_FALSE;
+   ctx->ATIFragmentShader.Current->ati.isValid = GL_FALSE;
+   ctx->ATIFragmentShader.Current->ati.swizzlerq = 0;
     ctx->ATIFragmentShader.Compiling = 1;
  #if MESA_DEBUG_ATI_FS
     _mesa_debug(ctx, "%s %u\n", __func__, ctx->ATIFragmentShader.Current->Id);
  #endif
  }
void GLAPIENTRY
  _mesa_EndFragmentShaderATI(void)
  {
     GET_CURRENT_CONTEXT(ctx);
-   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
+   struct gl_program *curProg = ctx->ATIFragmentShader.Current;
  #if MESA_DEBUG_ATI_FS
     GLint i, j;
  #endif
if (!ctx->ATIFragmentShader.Compiling) {
        _mesa_error(ctx, GL_INVALID_OPERATION, 
"glEndFragmentShaderATI(outsideShader)");
        return;
     }
-   if (curProg->interpinp1 && (ctx->ATIFragmentShader.Current->cur_pass > 1)) {
+   if (curProg->ati.interpinp1 && (ctx->ATIFragmentShader.Current->ati.cur_pass 
> 1)) {
        _mesa_error(ctx, GL_INVALID_OPERATION, 
"glEndFragmentShaderATI(interpinfirstpass)");
     /* according to spec, DON'T return here */
     }
match_pair_inst(curProg, 0);
     ctx->ATIFragmentShader.Compiling = 0;
-   ctx->ATIFragmentShader.Current->isValid = GL_TRUE;
-   if ((ctx->ATIFragmentShader.Current->cur_pass == 0) ||
-      (ctx->ATIFragmentShader.Current->cur_pass == 2)) {
+   ctx->ATIFragmentShader.Current->ati.isValid = GL_TRUE;
+   if ((ctx->ATIFragmentShader.Current->ati.cur_pass == 0) ||
+      (ctx->ATIFragmentShader.Current->ati.cur_pass == 2)) {
        _mesa_error(ctx, GL_INVALID_OPERATION, 
"glEndFragmentShaderATI(noarithinst)");
     }
-   if (ctx->ATIFragmentShader.Current->cur_pass > 1)
-      ctx->ATIFragmentShader.Current->NumPasses = 2;
+   if (ctx->ATIFragmentShader.Current->ati.cur_pass > 1)
+      ctx->ATIFragmentShader.Current->ati.NumPasses = 2;
     else
-      ctx->ATIFragmentShader.Current->NumPasses = 1;
+      ctx->ATIFragmentShader.Current->ati.NumPasses = 1;
- ctx->ATIFragmentShader.Current->cur_pass = 0;
+   ctx->ATIFragmentShader.Current->ati.cur_pass = 0;
#if MESA_DEBUG_ATI_FS
     for (j = 0; j < MAX_NUM_PASSES_ATI; j++) {
        for (i = 0; i < MAX_NUM_FRAGMENT_REGISTERS_ATI; i++) {
-        GLuint op = curProg->SetupInst[j][i].Opcode;
+        GLuint op = curProg->ati.SetupInst[j][i].Opcode;
         const char *op_enum = op > 5 ? _mesa_enum_to_string(op) : "0";
-        GLuint src = curProg->SetupInst[j][i].src;
-        GLuint swizzle = curProg->SetupInst[j][i].swizzle;
+        GLuint src = curProg->ati.SetupInst[j][i].src;
+        GLuint swizzle = curProg->ati.SetupInst[j][i].swizzle;
         fprintf(stderr, "%2d %04X %s %d %04X\n", i, op, op_enum, src,
              swizzle);
        }
-      for (i = 0; i < curProg->numArithInstr[j]; i++) {
-        GLuint op0 = curProg->Instructions[j][i].Opcode[0];
-        GLuint op1 = curProg->Instructions[j][i].Opcode[1];
+      for (i = 0; i < curProg->ati.numArithInstr[j]; i++) {
+        GLuint op0 = curProg->ati.Instructions[j][i].Opcode[0];
+        GLuint op1 = curProg->ati.Instructions[j][i].Opcode[1];
         const char *op0_enum = op0 > 5 ? _mesa_enum_to_string(op0) : "0";
         const char *op1_enum = op1 > 5 ? _mesa_enum_to_string(op1) : "0";
-        GLuint count0 = curProg->Instructions[j][i].ArgCount[0];
-        GLuint count1 = curProg->Instructions[j][i].ArgCount[1];
+        GLuint count0 = curProg->ati.Instructions[j][i].ArgCount[0];
+        GLuint count1 = curProg->ati.Instructions[j][i].ArgCount[1];
         fprintf(stderr, "%2d %04X %s %d %04X %s %d\n", i, op0, op0_enum, 
count0,
              op1, op1_enum, count1);
        }
     }
  #endif
- if (ctx->Driver.NewATIfs) {
-      struct gl_program *prog = ctx->Driver.NewATIfs(ctx,
-                                                     
ctx->ATIFragmentShader.Current);
-      _mesa_reference_program(ctx, &ctx->ATIFragmentShader.Current->Program, 
prog);
-   }
-
     if (!ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_SHADER_ATI,
-                                        curProg->Program)) {
-      ctx->ATIFragmentShader.Current->isValid = GL_FALSE;
+                                        curProg)) {
+      ctx->ATIFragmentShader.Current->ati.isValid = GL_FALSE;
        /* XXX is this the right error? */
        _mesa_error(ctx, GL_INVALID_OPERATION,
                    "glEndFragmentShaderATI(driver rejected shader)");
     }
  }
void GLAPIENTRY
  _mesa_PassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle)
  {
     GET_CURRENT_CONTEXT(ctx);
-   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
+   struct gl_program *curProg = ctx->ATIFragmentShader.Current;
     struct atifs_setupinst *curI;
if (!ctx->ATIFragmentShader.Compiling) {
        _mesa_error(ctx, GL_INVALID_OPERATION, 
"glPassTexCoordATI(outsideShader)");
        return;
     }
- if (curProg->cur_pass == 1) {
+   if (curProg->ati.cur_pass == 1) {
        match_pair_inst(curProg, 0);
-      curProg->cur_pass = 2;
+      curProg->ati.cur_pass = 2;
     }
-   if ((curProg->cur_pass > 2) ||
-      ((1 << (dst - GL_REG_0_ATI)) & curProg->regsAssigned[curProg->cur_pass 
>> 1])) {
+   if ((curProg->ati.cur_pass > 2) ||
+      ((1 << (dst - GL_REG_0_ATI)) & curProg->ati.regsAssigned[curProg->ati.cur_pass 
>> 1])) {
        _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoord(pass)");
        return;
     }
     if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI) ||
        ((dst - GL_REG_0_ATI) >= ctx->Const.MaxTextureUnits)) {
        _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(dst)");
        return;
     }
     if (((coord < GL_REG_0_ATI) || (coord > GL_REG_5_ATI)) &&
         ((coord < GL_TEXTURE0_ARB) || (coord > GL_TEXTURE7_ARB) ||
         ((coord - GL_TEXTURE0_ARB) >= ctx->Const.MaxTextureUnits))) {
        _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(coord)");
        return;
     }
-   if ((curProg->cur_pass == 0) && (coord >= GL_REG_0_ATI)) {
+   if ((curProg->ati.cur_pass == 0) && (coord >= GL_REG_0_ATI)) {
        _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(coord)");
        return;
     }
     if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= 
GL_SWIZZLE_STQ_DQ_ATI)) {
        _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(swizzle)");
        return;
     }
     if ((swizzle & 1) && (coord >= GL_REG_0_ATI)) {
        _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(swizzle)");
        return;
     }
     if (coord <= GL_TEXTURE7_ARB) {
        GLuint tmp = coord - GL_TEXTURE0_ARB;
-      if ((((curProg->swizzlerq >> (tmp * 2)) & 3) != 0) &&
-          (((swizzle & 1) + 1) != ((curProg->swizzlerq >> (tmp * 2)) & 3))) {
+      if ((((curProg->ati.swizzlerq >> (tmp * 2)) & 3) != 0) &&
+          (((swizzle & 1) + 1) != ((curProg->ati.swizzlerq >> (tmp * 2)) & 
3))) {
         _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(swizzle)");
         return;
        } else {
-        curProg->swizzlerq |= (((swizzle & 1) + 1) << (tmp * 2));
+        curProg->ati.swizzlerq |= (((swizzle & 1) + 1) << (tmp * 2));
        }
     }
- curProg->regsAssigned[curProg->cur_pass >> 1] |= 1 << (dst - GL_REG_0_ATI);
+   curProg->ati.regsAssigned[curProg->ati.cur_pass >> 1] |= 1 << (dst - 
GL_REG_0_ATI);
     new_tex_inst(curProg);
/* add the instructions */
-   curI = &curProg->SetupInst[curProg->cur_pass >> 1][dst - GL_REG_0_ATI];
+   curI = &curProg->ati.SetupInst[curProg->ati.cur_pass >> 1][dst - 
GL_REG_0_ATI];
curI->Opcode = ATI_FRAGMENT_SHADER_PASS_OP;
     curI->src = coord;
     curI->swizzle = swizzle;
#if MESA_DEBUG_ATI_FS
     _mesa_debug(ctx, "%s(%s, %s, %s)\n", __func__,
               _mesa_enum_to_string(dst), _mesa_enum_to_string(coord),
               _mesa_enum_to_string(swizzle));
  #endif
  }
void GLAPIENTRY
  _mesa_SampleMapATI(GLuint dst, GLuint interp, GLenum swizzle)
  {
     GET_CURRENT_CONTEXT(ctx);
-   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
+   struct gl_program *curProg = ctx->ATIFragmentShader.Current;
     struct atifs_setupinst *curI;
if (!ctx->ATIFragmentShader.Compiling) {
        _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(outsideShader)");
        return;
     }
- if (curProg->cur_pass == 1) {
+   if (curProg->ati.cur_pass == 1) {
        match_pair_inst(curProg, 0);
-      curProg->cur_pass = 2;
+      curProg->ati.cur_pass = 2;
     }
-   if ((curProg->cur_pass > 2) ||
-      ((1 << (dst - GL_REG_0_ATI)) & curProg->regsAssigned[curProg->cur_pass 
>> 1])) {
+   if ((curProg->ati.cur_pass > 2) ||
+      ((1 << (dst - GL_REG_0_ATI)) & curProg->ati.regsAssigned[curProg->ati.cur_pass 
>> 1])) {
        _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(pass)");
        return;
     }
     if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI) ||
        ((dst - GL_REG_0_ATI) >= ctx->Const.MaxTextureUnits)) {
        _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(dst)");
        return;
     }
     if (((interp < GL_REG_0_ATI) || (interp > GL_REG_5_ATI)) &&
         ((interp < GL_TEXTURE0_ARB) || (interp > GL_TEXTURE7_ARB) ||
         ((interp - GL_TEXTURE0_ARB) >= ctx->Const.MaxTextureUnits))) {
     /* is this texture5 or texture7? spec is a bit unclear there */
        _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(interp)");
        return;
     }
-   if ((curProg->cur_pass == 0) && (interp >= GL_REG_0_ATI)) {
+   if ((curProg->ati.cur_pass == 0) && (interp >= GL_REG_0_ATI)) {
        _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(interp)");
        return;
     }
     if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= 
GL_SWIZZLE_STQ_DQ_ATI)) {
        _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(swizzle)");
        return;
     }
     if ((swizzle & 1) && (interp >= GL_REG_0_ATI)) {
        _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(swizzle)");
        return;
     }
     if (interp <= GL_TEXTURE7_ARB) {
        GLuint tmp = interp - GL_TEXTURE0_ARB;
-      if ((((curProg->swizzlerq >> (tmp * 2)) & 3) != 0) &&
-          (((swizzle & 1) + 1) != ((curProg->swizzlerq >> (tmp * 2)) & 3))) {
+      if ((((curProg->ati.swizzlerq >> (tmp * 2)) & 3) != 0) &&
+          (((swizzle & 1) + 1) != ((curProg->ati.swizzlerq >> (tmp * 2)) & 
3))) {
         _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(swizzle)");
         return;
        } else {
-        curProg->swizzlerq |= (((swizzle & 1) + 1) << (tmp * 2));
+        curProg->ati.swizzlerq |= (((swizzle & 1) + 1) << (tmp * 2));
        }
     }
- curProg->regsAssigned[curProg->cur_pass >> 1] |= 1 << (dst - GL_REG_0_ATI);
+   curProg->ati.regsAssigned[curProg->ati.cur_pass >> 1] |= 1 << (dst - 
GL_REG_0_ATI);
     new_tex_inst(curProg);
/* add the instructions */
-   curI = &curProg->SetupInst[curProg->cur_pass >> 1][dst - GL_REG_0_ATI];
+   curI = &curProg->ati.SetupInst[curProg->ati.cur_pass >> 1][dst - 
GL_REG_0_ATI];
curI->Opcode = ATI_FRAGMENT_SHADER_SAMPLE_OP;
     curI->src = interp;
     curI->swizzle = swizzle;
#if MESA_DEBUG_ATI_FS
     _mesa_debug(ctx, "%s(%s, %s, %s)\n", __func__,
               _mesa_enum_to_string(dst), _mesa_enum_to_string(interp),
               _mesa_enum_to_string(swizzle));
  #endif
  }
static void
  _mesa_FragmentOpXATI(GLint optype, GLuint arg_count, GLenum op, GLuint dst,
                     GLuint dstMask, GLuint dstMod, GLuint arg1,
                     GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
                     GLuint arg2Rep, GLuint arg2Mod, GLuint arg3,
                     GLuint arg3Rep, GLuint arg3Mod)
  {
     GET_CURRENT_CONTEXT(ctx);
-   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
+   struct gl_program *curProg = ctx->ATIFragmentShader.Current;
     GLint ci;
     struct atifs_instruction *curI;
     GLuint modtemp = dstMod & ~GL_SATURATE_BIT_ATI;
if (!ctx->ATIFragmentShader.Compiling) {
        _mesa_error(ctx, GL_INVALID_OPERATION, 
"C/AFragmentOpATI(outsideShader)");
        return;
     }
- if (curProg->cur_pass==0)
-      curProg->cur_pass=1;
+   if (curProg->ati.cur_pass==0)
+      curProg->ati.cur_pass=1;
- else if (curProg->cur_pass==2)
-      curProg->cur_pass=3;
+   else if (curProg->ati.cur_pass==2)
+      curProg->ati.cur_pass=3;
/* decide whether this is a new instruction or not ... all color instructions are new,
        and alpha instructions might also be new if there was no preceding 
color inst */
-   if ((optype == 0) || (curProg->last_optype == optype)) {
-      if (curProg->numArithInstr[curProg->cur_pass >> 1] > 7) {
+   if ((optype == 0) || (curProg->ati.last_optype == optype)) {
+      if (curProg->ati.numArithInstr[curProg->ati.cur_pass >> 1] > 7) {
         _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(instrCount)");
         return;
        }
        /* easier to do that here slight side effect invalid instr will still 
be inserted as nops */
        match_pair_inst(curProg, optype);
        new_arith_inst(curProg);
     }
-   curProg->last_optype = optype;
-   ci = curProg->numArithInstr[curProg->cur_pass >> 1] - 1;
+   curProg->ati.last_optype = optype;
+   ci = curProg->ati.numArithInstr[curProg->ati.cur_pass >> 1] - 1;
/* add the instructions */
-   curI = &curProg->Instructions[curProg->cur_pass >> 1][ci];
+   curI = &curProg->ati.Instructions[curProg->ati.cur_pass >> 1][ci];
/* error checking */
     if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI)) {
        _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(dst)");
        return;
     }
     if ((modtemp != GL_NONE) && (modtemp != GL_2X_BIT_ATI) &&
        (modtemp != GL_4X_BIT_ATI) && (modtemp != GL_8X_BIT_ATI) &&
        (modtemp != GL_HALF_BIT_ATI) && !(modtemp != GL_QUARTER_BIT_ATI) &&
        (modtemp != GL_EIGHTH_BIT_ATI)) {
@@ -765,19 +750,19 @@ _mesa_SetFragmentShaderConstantATI(GLuint dst, const 
GLfloat * value)
     GET_CURRENT_CONTEXT(ctx);
if ((dst < GL_CON_0_ATI) || (dst > GL_CON_7_ATI)) {
        /* spec says nothing about what should happen here but we can't just 
segfault...*/
        _mesa_error(ctx, GL_INVALID_ENUM, 
"glSetFragmentShaderConstantATI(dst)");
        return;
     }
dstindex = dst - GL_CON_0_ATI;
     if (ctx->ATIFragmentShader.Compiling) {
-      struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
-      COPY_4V(curProg->Constants[dstindex], value);
-      curProg->LocalConstDef |= 1 << dstindex;
+      struct gl_program *curProg = ctx->ATIFragmentShader.Current;
+      COPY_4V(curProg->ati.Constants[dstindex], value);
+      curProg->ati.LocalConstDef |= 1 << dstindex;
     }
     else {
        FLUSH_VERTICES(ctx, _NEW_PROGRAM);
        COPY_4V(ctx->ATIFragmentShader.GlobalConstants[dstindex], value);
     }
  }
diff --git a/src/mesa/main/atifragshader.h b/src/mesa/main/atifragshader.h
index 0e32795da3..492e6db705 100644
--- a/src/mesa/main/atifragshader.h
+++ b/src/mesa/main/atifragshader.h
@@ -55,26 +55,26 @@ struct atifs_instruction
/* different from arithmetic shader instruction */
  struct atifs_setupinst
  {
     GLenum Opcode;
     GLuint src;
     GLenum swizzle;
  };
-extern struct ati_fragment_shader *
+extern struct gl_program *
  _mesa_new_ati_fragment_shader(struct gl_context *ctx, GLuint id);
extern void
  _mesa_delete_ati_fragment_shader(struct gl_context *ctx,
-                                 struct ati_fragment_shader *s);
+                                 struct gl_program *s);
extern GLuint GLAPIENTRY _mesa_GenFragmentShadersATI(GLuint range); extern void GLAPIENTRY _mesa_BindFragmentShaderATI(GLuint id); extern void GLAPIENTRY _mesa_DeleteFragmentShaderATI(GLuint id); extern void GLAPIENTRY _mesa_BeginFragmentShaderATI(void); diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index da03b2e8b9..1d77145942 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -452,25 +452,21 @@ struct dd_function_table {
/**
      * \name Vertex/fragment program functions
      */
     /*@{*/
     /** Allocate a new program */
     struct gl_program * (*NewProgram)(struct gl_context *ctx, GLenum target,
                                       GLuint id, bool is_arb_asm);
     /** Delete a program */
     void (*DeleteProgram)(struct gl_context *ctx, struct gl_program *prog);
-   /**
-    * Allocate a program to associate with the new ATI fragment shader 
(optional)
-    */
-   struct gl_program * (*NewATIfs)(struct gl_context *ctx,
-                                   struct ati_fragment_shader *curProg);
+
     /**
      * Notify driver that a program string (and GPU code) has been specified
      * or modified.  Return GL_TRUE or GL_FALSE to indicate if the program is
      * supported by the driver.
      */
     GLboolean (*ProgramStringNotify)(struct gl_context *ctx, GLenum target,
                                      struct gl_program *prog);
/**
      * Notify driver that the sampler uniforms for the current program have
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 6b5c5bbb36..7c357b07ee 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2058,20 +2058,27 @@ typedef enum
     PROGRAM_UNDEFINED,   /**< Invalid/TBD value */
     PROGRAM_IMMEDIATE,   /**< Immediate value, used by TGSI */
     PROGRAM_BUFFER,      /**< for shader buffers, compile-time only */
     PROGRAM_MEMORY,      /**< for shared, global and local memory */
     PROGRAM_IMAGE,       /**< for shader images, compile-time only */
     PROGRAM_HW_ATOMIC,   /**< for hw atomic counters, compile-time only */
     PROGRAM_FILE_MAX
  } gl_register_file;
+/**
+ * ATI_fragment_shader runtime state
+ */
+struct atifs_instruction;
+struct atifs_setupinst;
+
+
  /**
   * Base class for any kind of program object
   */
  struct gl_program
  {
     /** FIXME: This must be first until we split shader_info from nir_shader */
     struct shader_info info;
GLuint Id;
     GLint RefCount;
@@ -2236,20 +2243,37 @@ struct gl_program
           GLuint NumNativeAluInstructions;
           GLuint NumNativeTexInstructions;
           GLuint NumNativeTexIndirections;
           /*@}*/
/** Used by ARB assembly-style programs. Can only be true for vertex
            * programs.
            */
           GLboolean IsPositionInvariant;
        } arb;
+
+      /**  ATI fragment shader fields */
+      struct {
+         struct atifs_instruction *Instructions[2];
+         struct atifs_setupinst *SetupInst[2];
+         GLfloat Constants[8][4];
+         /** Indicates which constants have been set */
+         GLbitfield LocalConstDef;
+         GLubyte numArithInstr[2];
+         GLubyte regsAssigned[2];
+         GLubyte NumPasses;         /**< 1 or 2 */
+         GLubyte cur_pass;
+         GLubyte last_optype;
+         GLboolean interpinp1;
+         GLboolean isValid;
+         GLuint swizzlerq;
+      } ati;
     };
  };
/**
   * State common to vertex and fragment programs.
   */
  struct gl_program_state
  {
     GLint ErrorPos;                       /* GL_PROGRAM_ERROR_POSITION_ARB/NV 
*/
@@ -2352,58 +2376,29 @@ struct gl_fragment_program_state
   */
  struct gl_compute_program_state
  {
     /** Currently enabled and valid program (including internal programs
      * and compiled shader programs).
      */
     struct gl_program *_Current;
  };
-/**
- * ATI_fragment_shader runtime state
- */
-
-struct atifs_instruction;
-struct atifs_setupinst;
-
-/**
- * ATI fragment shader
- */
-struct ati_fragment_shader
-{
-   GLuint Id;
-   GLint RefCount;
-   struct atifs_instruction *Instructions[2];
-   struct atifs_setupinst *SetupInst[2];
-   GLfloat Constants[8][4];
-   GLbitfield LocalConstDef;  /**< Indicates which constants have been set */
-   GLubyte numArithInstr[2];
-   GLubyte regsAssigned[2];
-   GLubyte NumPasses;         /**< 1 or 2 */
-   GLubyte cur_pass;
-   GLubyte last_optype;
-   GLboolean interpinp1;
-   GLboolean isValid;
-   GLuint swizzlerq;
-   struct gl_program *Program;
-};
-
  /**
   * Context state for GL_ATI_fragment_shader
   */
  struct gl_ati_fragment_shader_state
  {
     GLboolean Enabled;
     GLboolean Compiling;
     GLfloat GlobalConstants[8][4];
-   struct ati_fragment_shader *Current;
+   struct gl_program *Current;
  };
/**
   *  Shader subroutine function definition
   */
  struct gl_subroutine_function
  {
     char *name;
     int index;
     int num_compat_types;
@@ -3250,21 +3245,21 @@ struct gl_shared_state
      * \name Vertex/geometry/fragment programs
      */
     /*@{*/
     struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */
     struct gl_program *DefaultVertexProgram;
     struct gl_program *DefaultFragmentProgram;
     /*@}*/
/* GL_ATI_fragment_shader */
     struct _mesa_HashTable *ATIShaders;
-   struct ati_fragment_shader *DefaultFragmentShader;
+   struct gl_program *DefaultFragmentShader;
struct _mesa_HashTable *BufferObjects; /** Table of both gl_shader and gl_shader_program objects */
     struct _mesa_HashTable *ShaderObjects;
/* GL_EXT_framebuffer_object */
     struct _mesa_HashTable *RenderBuffers;
     struct _mesa_HashTable *FrameBuffers;
diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c
index e3417a4df3..94148e5122 100644
--- a/src/mesa/main/shared.c
+++ b/src/mesa/main/shared.c
@@ -196,21 +196,21 @@ delete_program_cb(GLuint id, void *data, void *userData)
  }
/**
   * Callback for deleting an ATI fragment shader object.
   * Called by _mesa_HashDeleteAll().
   */
  static void
  delete_fragshader_cb(GLuint id, void *data, void *userData)
  {
-   struct ati_fragment_shader *shader = (struct ati_fragment_shader *) data;
+   struct gl_program *shader = (struct gl_program *) data;
     struct gl_context *ctx = (struct gl_context *) userData;
     _mesa_delete_ati_fragment_shader(ctx, shader);
  }
/**
   * Callback for deleting a buffer object.  Called by _mesa_HashDeleteAll().
   */
  static void
  delete_bufferobj_cb(GLuint id, void *data, void *userData)
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 7aec98e578..508cb57e7a 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -115,24 +115,24 @@ update_program(struct gl_context *ctx)
                                NULL);
     }
     else if (_mesa_arb_fragment_program_enabled(ctx)) {
        /* Use user-defined fragment program */
        _mesa_reference_program(ctx, &ctx->FragmentProgram._Current,
                                ctx->FragmentProgram.Current);
        _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram,
                              NULL);
     }
     else if (_mesa_ati_fragment_shader_enabled(ctx) &&
-            ctx->ATIFragmentShader.Current->Program) {
+            ctx->ATIFragmentShader.Current) {
         /* Use the enabled ATI fragment shader's associated program */
        _mesa_reference_program(ctx, &ctx->FragmentProgram._Current,
-                              ctx->ATIFragmentShader.Current->Program);
+                              ctx->ATIFragmentShader.Current);
        _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram,
                                NULL);
     }
     else if (ctx->FragmentProgram._MaintainTexEnvProgram) {
        /* Use fragment program generated from fixed-function state */
        struct gl_shader_program *f = 
_mesa_get_fixed_func_fragment_program(ctx);
_mesa_reference_program(ctx, &ctx->FragmentProgram._Current,
                              f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program);
        _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram,
diff --git a/src/mesa/main/state.h b/src/mesa/main/state.h
index b719f39296..beee001381 100644
--- a/src/mesa/main/state.h
+++ b/src/mesa/main/state.h
@@ -104,14 +104,14 @@ static inline bool
  _mesa_arb_fragment_program_enabled(const struct gl_context *ctx)
  {
     return ctx->FragmentProgram.Enabled &&
            ctx->FragmentProgram.Current->arb.Instructions;
  }
static inline bool
  _mesa_ati_fragment_shader_enabled(const struct gl_context *ctx)
  {
     return ctx->ATIFragmentShader.Enabled &&
-          ctx->ATIFragmentShader.Current->Instructions[0];
+          ctx->ATIFragmentShader.Current->ati.Instructions[0];
  }
#endif
diff --git a/src/mesa/program/program.c b/src/mesa/program/program.c
index faf5b7fa28..7f88cbed54 100644
--- a/src/mesa/program/program.c
+++ b/src/mesa/program/program.c
@@ -147,21 +147,21 @@ _mesa_update_default_objects_program(struct gl_context 
*ctx)
                              ctx->Shared->DefaultFragmentProgram);
     assert(ctx->FragmentProgram.Current);
/* XXX probably move this stuff */
     if (ctx->ATIFragmentShader.Current) {
        ctx->ATIFragmentShader.Current->RefCount--;
        if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
           free(ctx->ATIFragmentShader.Current);
        }
     }
-   ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) 
ctx->Shared->DefaultFragmentShader;
+   ctx->ATIFragmentShader.Current = ctx->Shared->DefaultFragmentShader;
     assert(ctx->ATIFragmentShader.Current);
     ctx->ATIFragmentShader.Current->RefCount++;
  }
/**
   * Set the vertex/fragment program error state (position and error string).
   * This is generally called from within the parsers.
   */
  void
@@ -229,20 +229,21 @@ _mesa_init_gl_program(struct gl_program *prog, GLenum 
target, GLuint id,
  struct gl_program *
  _mesa_new_program(struct gl_context *ctx, GLenum target, GLuint id,
                    bool is_arb_asm)
  {
     switch (target) {
     case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */
     case GL_GEOMETRY_PROGRAM_NV:
     case GL_TESS_CONTROL_PROGRAM_NV:
     case GL_TESS_EVALUATION_PROGRAM_NV:
     case GL_FRAGMENT_PROGRAM_ARB:
+   case GL_FRAGMENT_SHADER_ATI:
     case GL_COMPUTE_PROGRAM_NV: {
        struct gl_program *prog = rzalloc(NULL, struct gl_program);
        return _mesa_init_gl_program(prog, target, id, is_arb_asm);
     }
     default:
        _mesa_problem(ctx, "bad target in _mesa_new_program");
        return NULL;
     }
  }
diff --git a/src/mesa/state_tracker/st_atifs_to_tgsi.c b/src/mesa/state_tracker/st_atifs_to_tgsi.c
index 8affbdc8d1..0bd082e6ff 100644
--- a/src/mesa/state_tracker/st_atifs_to_tgsi.c
+++ b/src/mesa/state_tracker/st_atifs_to_tgsi.c
@@ -30,21 +30,21 @@
  #include "tgsi/tgsi_transform.h"
#include "st_program.h"
  #include "st_atifs_to_tgsi.h"
/**
   * Intermediate state used during shader translation.
   */
  struct st_translate {
     struct ureg_program *ureg;
-   struct ati_fragment_shader *atifs;
+   struct gl_program *atifs;
struct ureg_dst temps[MAX_PROGRAM_TEMPS];
     struct ureg_src *constants;
     struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS];
     struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS];
     struct ureg_src samplers[PIPE_MAX_SAMPLERS];
const ubyte *inputMapping;
     const ubyte *outputMapping;
@@ -414,21 +414,20 @@ finalize_shader(struct st_translate *t, unsigned numPasses)
     ureg_insn(t->ureg, TGSI_OPCODE_END, dst, 0, src, 0, 0);
  }
/**
   * Called when a new variant is needed, we need to translate
   * the ATI fragment shader to TGSI
   */
  enum pipe_error
  st_translate_atifs_program(
     struct ureg_program *ureg,
-   struct ati_fragment_shader *atifs,
     struct gl_program *program,
     GLuint numInputs,
     const ubyte inputMapping[],
     const ubyte inputSemanticName[],
     const ubyte inputSemanticIndex[],
     const ubyte interpMode[],
     GLuint numOutputs,
     const ubyte outputMapping[],
     const ubyte outputSemanticName[],
     const ubyte outputSemanticIndex[])
@@ -437,21 +436,20 @@ st_translate_atifs_program(
unsigned pass, i, r; struct st_translate translate, *t;
     t = &translate;
     memset(t, 0, sizeof *t);
t->inputMapping = inputMapping;
     t->outputMapping = outputMapping;
     t->ureg = ureg;
-   t->atifs = atifs;
/*
      * Declare input attributes.
      */
     for (i = 0; i < numInputs; i++) {
        t->inputs[i] = ureg_DECL_fs_input(ureg,
                                          inputSemanticName[i],
                                          inputSemanticIndex[i],
                                          interpMode[i]);
     }
@@ -500,90 +498,86 @@ st_translate_atifs_program(
           /* the texture target is still unknown, it will be fixed in the draw 
call */
           ureg_DECL_sampler_view(ureg, i, TGSI_TEXTURE_2D,
                                  TGSI_RETURN_TYPE_FLOAT,
                                  TGSI_RETURN_TYPE_FLOAT,
                                  TGSI_RETURN_TYPE_FLOAT,
                                  TGSI_RETURN_TYPE_FLOAT);
        }
     }
/* emit instructions */
-   for (pass = 0; pass < atifs->NumPasses; pass++) {
+   for (pass = 0; pass < program->ati.NumPasses; pass++) {
        t->current_pass = pass;
        for (r = 0; r < MAX_NUM_FRAGMENT_REGISTERS_ATI; r++) {
-         struct atifs_setupinst *texinst = &atifs->SetupInst[pass][r];
+         struct atifs_setupinst *texinst = &program->ati.SetupInst[pass][r];
           compile_setupinst(t, r, texinst);
        }
-      for (i = 0; i < atifs->numArithInstr[pass]; i++) {
-         struct atifs_instruction *inst = &atifs->Instructions[pass][i];
+      for (i = 0; i < program->ati.numArithInstr[pass]; i++) {
+         struct atifs_instruction *inst = &program->ati.Instructions[pass][i];
           compile_instruction(t, inst);
        }
     }
- finalize_shader(t, atifs->NumPasses);
+   finalize_shader(t, program->ati.NumPasses);
out:
     free(t->constants);
if (t->error) {
        debug_printf("%s: translate error flag set\n", __func__);
     }
return ret;
  }
/**
   * Called in ProgramStringNotify, we need to fill the metadata of the
   * gl_program attached to the ati_fragment_shader
   */
  void
  st_init_atifs_prog(struct gl_context *ctx, struct gl_program *prog)
  {
-   /* we know this is st_fragment_program, because of st_new_ati_fs() */
-   struct st_fragment_program *stfp = (struct st_fragment_program *) prog;
-   struct ati_fragment_shader *atifs = stfp->ati_fs;
-
     unsigned pass, i, r, optype, arg;
static const gl_state_index fog_params_state[STATE_LENGTH] =
        {STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED, 0, 0, 0};
     static const gl_state_index fog_color[STATE_LENGTH] =
        {STATE_FOG_COLOR, 0, 0, 0, 0};
prog->info.inputs_read = 0;
     prog->info.outputs_written = BITFIELD64_BIT(FRAG_RESULT_COLOR);
     prog->SamplersUsed = 0;
     prog->Parameters = _mesa_new_parameter_list();
/* fill in inputs_read, SamplersUsed, TexturesUsed */
-   for (pass = 0; pass < atifs->NumPasses; pass++) {
+   for (pass = 0; pass < prog->ati.NumPasses; pass++) {
        for (r = 0; r < MAX_NUM_FRAGMENT_REGISTERS_ATI; r++) {
-         struct atifs_setupinst *texinst = &atifs->SetupInst[pass][r];
+         struct atifs_setupinst *texinst = &prog->ati.SetupInst[pass][r];
           GLuint pass_tex = texinst->src;
if (texinst->Opcode == ATI_FRAGMENT_SHADER_SAMPLE_OP) {
              /* mark which texcoords are used */
              prog->info.inputs_read |= BITFIELD64_BIT(VARYING_SLOT_TEX0 + 
pass_tex - GL_TEXTURE0_ARB);
              /* by default there is 1:1 mapping between samplers and textures 
*/
              prog->SamplersUsed |= (1 << r);
              /* the target is unknown here, it will be fixed in the draw call 
*/
              prog->TexturesUsed[r] = TEXTURE_2D_BIT;
           } else if (texinst->Opcode == ATI_FRAGMENT_SHADER_PASS_OP) {
              if (pass_tex >= GL_TEXTURE0_ARB && pass_tex <= GL_TEXTURE7_ARB) {
                 prog->info.inputs_read |= BITFIELD64_BIT(VARYING_SLOT_TEX0 + 
pass_tex - GL_TEXTURE0_ARB);
              }
           }
        }
     }
-   for (pass = 0; pass < atifs->NumPasses; pass++) {
-      for (i = 0; i < atifs->numArithInstr[pass]; i++) {
-         struct atifs_instruction *inst = &atifs->Instructions[pass][i];
+   for (pass = 0; pass < prog->ati.NumPasses; pass++) {
+      for (i = 0; i < prog->ati.numArithInstr[pass]; i++) {
+         struct atifs_instruction *inst = &prog->ati.Instructions[pass][i];
for (optype = 0; optype < 2; optype++) { /* color, alpha */
              if (inst->Opcode[optype]) {
                 for (arg = 0; arg < inst->ArgCount[optype]; arg++) {
                    GLint index = inst->SrcReg[optype][arg].Index;
                    if (index == GL_PRIMARY_COLOR_EXT) {
                       prog->info.inputs_read |= 
BITFIELD64_BIT(VARYING_SLOT_COL0);
                    } else if (index == GL_SECONDARY_INTERPOLATOR_ATI) {
                       /* note: ATI_fragment_shader.txt never specifies what
                        * GL_SECONDARY_INTERPOLATOR_ATI is, swrast uses
diff --git a/src/mesa/state_tracker/st_atifs_to_tgsi.h 
b/src/mesa/state_tracker/st_atifs_to_tgsi.h
index ce547911cf..f532c654f6 100644
--- a/src/mesa/state_tracker/st_atifs_to_tgsi.h
+++ b/src/mesa/state_tracker/st_atifs_to_tgsi.h
@@ -27,27 +27,25 @@
  #include "pipe/p_defines.h"
#if defined __cplusplus
  extern "C" {
  #endif
struct gl_context;
  struct gl_program;
  struct ureg_program;
  struct tgsi_token;
-struct ati_fragment_shader;
  struct st_fp_variant_key;
enum pipe_error
  st_translate_atifs_program(
      struct ureg_program *ureg,
-    struct ati_fragment_shader *atifs,
      struct gl_program *program,
      GLuint numInputs,
      const ubyte inputMapping[],
      const ubyte inputSemanticName[],
      const ubyte inputSemanticIndex[],
      const ubyte interpMode[],
      GLuint numOutputs,
      const ubyte outputMapping[],
      const ubyte outputSemanticName[],
      const ubyte outputSemanticIndex[]);
diff --git a/src/mesa/state_tracker/st_atom_constbuf.c 
b/src/mesa/state_tracker/st_atom_constbuf.c
index 497d33fc34..910370b785 100644
--- a/src/mesa/state_tracker/st_atom_constbuf.c
+++ b/src/mesa/state_tracker/st_atom_constbuf.c
@@ -59,28 +59,29 @@ void st_upload_constants(struct st_context *st, struct 
gl_program *prog)
     enum pipe_shader_type shader_type = pipe_shader_type_from_mesa(stage);
assert(shader_type == PIPE_SHADER_VERTEX ||
            shader_type == PIPE_SHADER_FRAGMENT ||
            shader_type == PIPE_SHADER_GEOMETRY ||
            shader_type == PIPE_SHADER_TESS_CTRL ||
            shader_type == PIPE_SHADER_TESS_EVAL ||
            shader_type == PIPE_SHADER_COMPUTE);
/* update the ATI constants before rendering */
-   if (shader_type == PIPE_SHADER_FRAGMENT && st->fp->ati_fs) {
-      struct ati_fragment_shader *ati_fs = st->fp->ati_fs;
+   if (shader_type == PIPE_SHADER_FRAGMENT &&
+       st->fp->Base.Target == GL_FRAGMENT_SHADER_ATI) {
+      struct gl_program *ati_fs = &st->fp->Base;
        unsigned c;
for (c = 0; c < MAX_NUM_FRAGMENT_CONSTANTS_ATI; c++) {
-         if (ati_fs->LocalConstDef & (1 << c))
+         if (ati_fs->ati.LocalConstDef & (1 << c))
              memcpy(params->ParameterValues[c],
-                   ati_fs->Constants[c], sizeof(GLfloat) * 4);
+                   ati_fs->ati.Constants[c], sizeof(GLfloat) * 4);
           else
              memcpy(params->ParameterValues[c],
                     st->ctx->ATIFragmentShader.GlobalConstants[c], 
sizeof(GLfloat) * 4);
        }
     }
/* Make all bindless samplers/images bound texture/image units resident in
      * the context.
      */
     st_make_bound_samplers_resident(st, prog);
diff --git a/src/mesa/state_tracker/st_atom_shader.c 
b/src/mesa/state_tracker/st_atom_shader.c
index c6faa3f07f..1b1205cfb2 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -94,26 +94,28 @@ get_texture_target(struct gl_context *ctx, const unsigned 
unit)
   * Mesa fragment program into a gallium fragment program and binding it.
   */
  void
  st_update_fp( struct st_context *st )
  {
     struct st_fragment_program *stfp;
     struct st_fp_variant_key key;
assert(st->ctx->FragmentProgram._Current);
     stfp = st_fragment_program(st->ctx->FragmentProgram._Current);
-   assert(stfp->Base.Target == GL_FRAGMENT_PROGRAM_ARB);
+   assert(stfp->Base.Target == GL_FRAGMENT_PROGRAM_ARB ||
+          stfp->Base.Target == GL_FRAGMENT_SHADER_ATI);
void *shader; if (st->shader_has_one_variant[MESA_SHADER_FRAGMENT] &&
-       !stfp->ati_fs && /* ATI_fragment_shader always has multiple variants */
+       /* ATI_fragment_shader always has multiple variants */
+       stfp->Base.Target != GL_FRAGMENT_SHADER_ATI &&
         !stfp->Base.ExternalSamplersUsed && /* external samplers need variants 
*/
         stfp->variants &&
         !stfp->variants->key.drawpixels &&
         !stfp->variants->key.bitmap) {
        shader = stfp->variants->driver_shader;
     } else {
        memset(&key, 0, sizeof(key));
        key.st = st->has_shareable_shaders ? NULL : st;
/* _NEW_FRAG_CLAMP */
@@ -121,21 +123,21 @@ st_update_fp( struct st_context *st )
                          st->ctx->Color._ClampFragmentColor;
/* _NEW_MULTISAMPLE | _NEW_BUFFERS */
        key.persample_shading =
           st->force_persample_in_shader &&
           _mesa_is_multisample_enabled(st->ctx) &&
           st->ctx->Multisample.SampleShading &&
           st->ctx->Multisample.MinSampleShadingValue *
           _mesa_geometric_samples(st->ctx->DrawBuffer) > 1;
- if (stfp->ati_fs) {
+      if (stfp->Base.Target == GL_FRAGMENT_SHADER_ATI) {
           key.fog = st->ctx->Fog._PackedEnabledMode;
for (unsigned u = 0; u < MAX_NUM_FRAGMENT_REGISTERS_ATI; u++) {
              key.texture_targets[u] = get_texture_target(st->ctx, u);
           }
        }
key.external = st_get_external_sampler_key(st, &stfp->Base); shader = st_get_fp_variant(st, stfp, &key)->driver_shader;
diff --git a/src/mesa/state_tracker/st_cb_program.c 
b/src/mesa/state_tracker/st_cb_program.c
index 555fc5d5ad..062812c939 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -56,20 +56,21 @@
  static struct gl_program *
  st_new_program(struct gl_context *ctx, GLenum target, GLuint id,
                 bool is_arb_asm)
  {
     switch (target) {
     case GL_VERTEX_PROGRAM_ARB: {
        struct st_vertex_program *prog = rzalloc(NULL,
                                                 struct st_vertex_program);
        return _mesa_init_gl_program(&prog->Base, target, id, is_arb_asm);
     }
+   case GL_FRAGMENT_SHADER_ATI:
     case GL_FRAGMENT_PROGRAM_ARB: {
        struct st_fragment_program *prog = rzalloc(NULL,
                                                   struct st_fragment_program);
        return _mesa_init_gl_program(&prog->Base, target, id, is_arb_asm);
     }
     case GL_TESS_CONTROL_PROGRAM_NV:
     case GL_TESS_EVALUATION_PROGRAM_NV:
     case GL_GEOMETRY_PROGRAM_NV: {
        struct st_common_program *prog = rzalloc(NULL,
                                                 struct st_common_program);
@@ -111,20 +112,21 @@ st_delete_program(struct gl_context *ctx, struct 
gl_program *prog)
        {
           struct st_common_program *p = st_common_program(prog);
st_release_basic_variants(st, p->Base.Target, &p->variants,
                                     &p->tgsi);
if (p->glsl_to_tgsi)
              free_glsl_to_tgsi_visitor(p->glsl_to_tgsi);
        }
        break;
+   case GL_FRAGMENT_SHADER_ATI:
     case GL_FRAGMENT_PROGRAM_ARB:
        {
           struct st_fragment_program *stfp =
              (struct st_fragment_program *) prog;
st_release_fp_variants(st, stfp); if (stfp->glsl_to_tgsi)
              free_glsl_to_tgsi_visitor(stfp->glsl_to_tgsi);
        }
@@ -225,57 +227,41 @@ st_program_string_notify( struct gl_context *ctx,
        if (!st_translate_compute_program(st, stcp))
           return false;
if (st->cp == stcp)
           st->dirty |= stcp->affected_states;
     }
     else if (target == GL_FRAGMENT_SHADER_ATI) {
        assert(prog);
struct st_fragment_program *stfp = (struct st_fragment_program *) prog;
-      assert(stfp->ati_fs);
-      assert(stfp->ati_fs->Program == prog);
+      assert(stfp->Base.Target == GL_FRAGMENT_SHADER_ATI);
st_init_atifs_prog(ctx, prog); st_release_fp_variants(st, stfp);
        if (!st_translate_fragment_program(st, stfp))
           return false;
if (st->fp == stfp)
           st->dirty |= stfp->affected_states;
     }
if (ST_DEBUG & DEBUG_PRECOMPILE ||
         st->shader_has_one_variant[stage])
        st_precompile_shader_variant(st, prog);
return GL_TRUE;
  }
-/**
- * Called via ctx->Driver.NewATIfs()
- * Called in glEndFragmentShaderATI()
- */
-static struct gl_program *
-st_new_ati_fs(struct gl_context *ctx, struct ati_fragment_shader *curProg)
-{
-   struct gl_program *prog = ctx->Driver.NewProgram(ctx, 
GL_FRAGMENT_PROGRAM_ARB,
-         curProg->Id, true);
-   struct st_fragment_program *stfp = (struct st_fragment_program *)prog;
-   stfp->ati_fs = curProg;
-   return prog;
-}
-
  /**
   * Plug in the program and shader-related device driver functions.
   */
  void
  st_init_program_functions(struct dd_function_table *functions)
  {
     functions->NewProgram = st_new_program;
     functions->DeleteProgram = st_delete_program;
     functions->ProgramStringNotify = st_program_string_notify;
-   functions->NewATIfs = st_new_ati_fs;
functions->LinkShader = st_link_shader;
  }
diff --git a/src/mesa/state_tracker/st_program.c 
b/src/mesa/state_tracker/st_program.c
index e3649a8b7c..cdadd88ed0 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -662,21 +662,21 @@ st_translate_fragment_program(struct st_context *st,
/* This determines which states will be updated when the assembly
         * shader is bound.
         *
         * fragment.position and glDrawPixels always use constants.
         */
        stfp->affected_states = ST_NEW_FS_STATE |
                                ST_NEW_SAMPLE_SHADING |
                                ST_NEW_FS_CONSTANTS;
- if (stfp->ati_fs) {
+      if (stfp->Base.Target == GL_FRAGMENT_SHADER_ATI) {
           /* Just set them for ATI_fs unconditionally. */
           stfp->affected_states |= ST_NEW_FS_SAMPLER_VIEWS |
                                    ST_NEW_FS_SAMPLERS;
        } else {
           /* ARB_fp */
           if (stfp->Base.SamplersUsed)
              stfp->affected_states |= ST_NEW_FS_SAMPLER_VIEWS |
                                       ST_NEW_FS_SAMPLERS;
        }
     }
@@ -941,23 +941,22 @@ st_translate_fragment_program(struct st_context *st,
                             input_semantic_name,
                             input_semantic_index,
                             interpMode,
                             /* outputs */
                             fs_num_outputs,
                             outputMapping,
                             fs_output_semantic_name,
                             fs_output_semantic_index);
free_glsl_to_tgsi_visitor(stfp->glsl_to_tgsi);
-   } else if (stfp->ati_fs)
+   } else if (stfp->Base.Target == GL_FRAGMENT_SHADER_ATI)
        st_translate_atifs_program(ureg,
-                                 stfp->ati_fs,
                                   &stfp->Base,
                                   /* inputs */
                                   fs_num_inputs,
                                   inputMapping,
                                   input_semantic_name,
                                   input_semantic_index,
                                   interpMode,
                                   /* outputs */
                                   fs_num_outputs,
                                   outputMapping,
@@ -1091,21 +1090,21 @@ st_create_fp_variant(struct st_context *st,
        variant->key = *key;
return variant;
     }
tgsi.tokens = stfp->tgsi.tokens; assert(!(key->bitmap && key->drawpixels)); /* Fix texture targets and add fog for ATI_fs */
-   if (stfp->ati_fs) {
+   if (stfp->Base.Target == GL_FRAGMENT_SHADER_ATI) {
        const struct tgsi_token *tokens = st_fixup_atifs(tgsi.tokens, key);
if (tokens)
           tgsi.tokens = tokens;
        else
           fprintf(stderr, "mesa: cannot post-process ATI_fs\n");
     }
/* Emulate features. */
     if (key->clamp_color || key->persample_shading) {
diff --git a/src/mesa/state_tracker/st_program.h 
b/src/mesa/state_tracker/st_program.h
index 6049fba517..b834a1f368 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -136,21 +136,20 @@ struct st_fp_variant
/**
   * Derived from Mesa gl_program:
   */
  struct st_fragment_program
  {
     struct gl_program Base;
     struct pipe_shader_state tgsi;
     struct glsl_to_tgsi_visitor* glsl_to_tgsi;
-   struct ati_fragment_shader *ati_fs;
     uint64_t affected_states; /**< ST_NEW_* flags to mark dirty when binding */
/* used when bypassing glsl_to_tgsi: */
     struct gl_shader_program *shader_program;
struct st_fp_variant *variants; /** SHA1 hash of linked tgsi shader program, used for on-disk cache */
     unsigned char sha1[20];
  };
diff --git a/src/mesa/swrast/s_atifragshader.c 
b/src/mesa/swrast/s_atifragshader.c
index 414a4144e2..21d480fee4 100644
--- a/src/mesa/swrast/s_atifragshader.c
+++ b/src/mesa/swrast/s_atifragshader.c
@@ -292,62 +292,62 @@ do {                                              \
  /**
   * Execute the given fragment shader.
   * NOTE: we do everything in single-precision floating point
   * \param ctx - rendering context
   * \param shader - the shader to execute
   * \param machine - virtual machine state
   * \param span - the SWspan we're operating on
   * \param column - which pixel [i] we're operating on in the span
   */
  static void
-execute_shader(struct gl_context *ctx, const struct ati_fragment_shader 
*shader,
+execute_shader(struct gl_context *ctx, const struct gl_program *shader,
               struct atifs_machine *machine, const SWspan *span,
                 GLuint column)
  {
     GLuint pc;
     struct atifs_instruction *inst;
     struct atifs_setupinst *texinst;
     GLint optype;
     GLuint i;
     GLint j, pass;
     GLint dstreg;
     GLfloat src[2][3][4];
     GLfloat zeros[4] = { 0.0, 0.0, 0.0, 0.0 };
     GLfloat ones[4] = { 1.0, 1.0, 1.0, 1.0 };
     GLfloat dst[2][4], *dstp;
- for (pass = 0; pass < shader->NumPasses; pass++) {
+   for (pass = 0; pass < shader->ati.NumPasses; pass++) {
        if (pass > 0)
         finish_pass(machine);
        for (j = 0; j < MAX_NUM_FRAGMENT_REGISTERS_ATI; j++) {
-        texinst = &shader->SetupInst[pass][j];
+        texinst = &shader->ati.SetupInst[pass][j];
         if (texinst->Opcode == ATI_FRAGMENT_SHADER_PASS_OP)
            handle_pass_op(machine, texinst, span, column, j);
         else if (texinst->Opcode == ATI_FRAGMENT_SHADER_SAMPLE_OP)
            handle_sample_op(ctx, machine, texinst, span, column, j);
        }
- for (pc = 0; pc < shader->numArithInstr[pass]; pc++) {
-        inst = &shader->Instructions[pass][pc];
+      for (pc = 0; pc < shader->ati.numArithInstr[pass]; pc++) {
+        inst = &shader->ati.Instructions[pass][pc];
/* setup the source registers for color and alpha ops */
         for (optype = 0; optype < 2; optype++) {
            for (i = 0; i < inst->ArgCount[optype]; i++) {
               GLint index = inst->SrcReg[optype][i].Index;
if (index >= GL_REG_0_ATI && index <= GL_REG_5_ATI)
                  SETUP_SRC_REG(optype, i,
                                machine->Registers[index - GL_REG_0_ATI]);
               else if (index >= GL_CON_0_ATI && index <= GL_CON_7_ATI) {
-                 if (shader->LocalConstDef & (1 << (index - GL_CON_0_ATI))) {
+                 if (shader->ati.LocalConstDef & (1 << (index - 
GL_CON_0_ATI))) {
                     SETUP_SRC_REG(optype, i,
-                               shader->Constants[index - GL_CON_0_ATI]);
+                               shader->ati.Constants[index - GL_CON_0_ATI]);
                  } else {
                     SETUP_SRC_REG(optype, i,
                                ctx->ATIFragmentShader.GlobalConstants[index - 
GL_CON_0_ATI]);
                  }
               }
               else if (index == GL_ONE)
                  SETUP_SRC_REG(optype, i, ones);
               else if (index == GL_ZERO)
                  SETUP_SRC_REG(optype, i, zeros);
               else if (index == GL_PRIMARY_COLOR_EXT)
@@ -537,21 +537,21 @@ execute_shader(struct gl_context *ctx, const struct 
ati_fragment_shader *shader,
        }
     }
  }
/**
   * Init fragment shader virtual machine state.
   */
  static void
  init_machine(struct gl_context * ctx, struct atifs_machine *machine,
-            const struct ati_fragment_shader *shader,
+            const struct gl_program *shader,
             const SWspan *span, GLuint col)
  {
     GLfloat (*inputs)[4] = machine->Inputs;
     GLint i, j;
for (i = 0; i < 6; i++) {
        for (j = 0; j < 4; j++)
         machine->Registers[i][j] = 0.0;
     }
@@ -560,21 +560,21 @@ init_machine(struct gl_context * ctx, struct atifs_machine *machine,
  }
/**
   * Execute the current ATI shader program, operating on the given span.
   */
  void
  _swrast_exec_fragment_shader(struct gl_context * ctx, SWspan *span)
  {
-   const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current;
+   const struct gl_program *shader = ctx->ATIFragmentShader.Current;
     struct atifs_machine machine;
     GLuint i;
/* incoming colors should be floats */
     assert(span->array->ChanType == GL_FLOAT);
for (i = 0; i < span->end; i++) {
        if (span->array->mask[i]) {
         init_machine(ctx, &machine, shader, span, i);


_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to