[Mesa-dev] [PATCH] st/atifs: merge gl_program and ati_fragment_shader

Timothy Arceri tarceri at itsqueeze.com
Sat Nov 11 23:06:49 UTC 2017


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é <mtmkls at 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);
> 
> 


More information about the mesa-dev mailing list