On 12/11/17 04:10, Miklós Máté wrote:
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.

Thanks for testing :) Is there something freely available I can test this with? Are your piglit tests in a state where I could pull the repo and use what you have?


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