Fix setting indent-tabs-mode in the Emacs .dir-locals.el files
[mesa.git] / src / mesa / drivers / dri / r200 / r200_vertprog.c
index 620f29b5c6e0537be00abf8286a77bb32944d90d..7076ec0c7f377356019c4a46573c1ad5ed0ffae1 100644 (file)
@@ -30,14 +30,16 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
  *   Aapo Tahkola <aet@rasterburn.org>
  *   Roland Scheidegger <rscheidegger_lists@hispeed.ch>
  */
+
+#include "main/errors.h"
 #include "main/glheader.h"
 #include "main/macros.h"
 #include "main/enums.h"
-#include "shader/program.h"
-#include "shader/prog_instruction.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_statevars.h"
-#include "shader/programopt.h"
+#include "program/program.h"
+#include "program/prog_instruction.h"
+#include "program/prog_parameter.h"
+#include "program/prog_statevars.h"
+#include "program/programopt.h"
 #include "tnl/tnl.h"
 
 #include "r200_context.h"
@@ -95,44 +97,44 @@ static struct{
    OPN(SUB, 2),
    OPN(SWZ, 1),
    OPN(XPD, 2),
-   OPN(PRINT, 0),
    OPN(END, 0),
 };
 #undef OPN
 
-static GLboolean r200VertexProgUpdateParams(GLcontext *ctx, struct r200_vertex_program *vp)
+static GLboolean r200VertexProgUpdateParams(struct gl_context *ctx, struct r200_vertex_program *vp)
 {
    r200ContextPtr rmesa = R200_CONTEXT( ctx );
    GLfloat *fcmd = (GLfloat *)&rmesa->hw.vpp[0].cmd[VPP_CMD_0 + 1];
    int pi;
-   struct gl_vertex_program *mesa_vp = &vp->mesa_program;
+   struct gl_program *mesa_vp = &vp->mesa_program;
    struct gl_program_parameter_list *paramList;
    drm_radeon_cmd_header_t tmp;
 
    R200_STATECHANGE( rmesa, vpp[0] );
    R200_STATECHANGE( rmesa, vpp[1] );
-   assert(mesa_vp->Base.Parameters);
-   _mesa_load_state_parameters(ctx, mesa_vp->Base.Parameters);
-   paramList = mesa_vp->Base.Parameters;
+   assert(mesa_vp->Parameters);
+   _mesa_load_state_parameters(ctx, mesa_vp->Parameters);
+   paramList = mesa_vp->Parameters;
 
    if(paramList->NumParameters > R200_VSF_MAX_PARAM){
-      fprintf(stderr, "%s:Params exhausted\n", __FUNCTION__);
+      fprintf(stderr, "%s:Params exhausted\n", __func__);
       return GL_FALSE;
    }
 
    for(pi = 0; pi < paramList->NumParameters; pi++) {
+      unsigned pvo = paramList->ParameterValueOffset[pi];
+
       switch(paramList->Parameters[pi].Type) {
       case PROGRAM_STATE_VAR:
-      case PROGRAM_NAMED_PARAM:
       //fprintf(stderr, "%s", vp->Parameters->Parameters[pi].Name);
       case PROGRAM_CONSTANT:
-        *fcmd++ = paramList->ParameterValues[pi][0];
-        *fcmd++ = paramList->ParameterValues[pi][1];
-        *fcmd++ = paramList->ParameterValues[pi][2];
-        *fcmd++ = paramList->ParameterValues[pi][3];
+        *fcmd++ = paramList->ParameterValues[pvo + 0].f;
+        *fcmd++ = paramList->ParameterValues[pvo + 1].f;
+        *fcmd++ = paramList->ParameterValues[pvo + 2].f;
+        *fcmd++ = paramList->ParameterValues[pvo + 3].f;
         break;
       default:
-        _mesa_problem(NULL, "Bad param type in %s", __FUNCTION__);
+        _mesa_problem(NULL, "Bad param type in %s", __func__);
         break;
       }
       if (pi == 95) {
@@ -154,7 +156,7 @@ static GLboolean r200VertexProgUpdateParams(GLcontext *ctx, struct r200_vertex_p
    return GL_TRUE;
 }
 
-static INLINE unsigned long t_dst_mask(GLuint mask)
+static inline unsigned long t_dst_mask(GLuint mask)
 {
    /* WRITEMASK_* is equivalent to VSF_FLAG_* */
    return mask & VSF_FLAG_ALL;
@@ -168,27 +170,27 @@ static unsigned long t_dst(struct prog_dst_register *dst)
         | R200_VSF_OUT_CLASS_TMP);
    case PROGRAM_OUTPUT:
       switch (dst->Index) {
-      case VERT_RESULT_HPOS:
+      case VARYING_SLOT_POS:
         return R200_VSF_OUT_CLASS_RESULT_POS;
-      case VERT_RESULT_COL0:
+      case VARYING_SLOT_COL0:
         return R200_VSF_OUT_CLASS_RESULT_COLOR;
-      case VERT_RESULT_COL1:
+      case VARYING_SLOT_COL1:
         return ((1 << R200_VPI_OUT_REG_INDEX_SHIFT)
            | R200_VSF_OUT_CLASS_RESULT_COLOR);
-      case VERT_RESULT_FOGC:
+      case VARYING_SLOT_FOGC:
         return R200_VSF_OUT_CLASS_RESULT_FOGC;
-      case VERT_RESULT_TEX0:
-      case VERT_RESULT_TEX1:
-      case VERT_RESULT_TEX2:
-      case VERT_RESULT_TEX3:
-      case VERT_RESULT_TEX4:
-      case VERT_RESULT_TEX5:
-        return (((dst->Index - VERT_RESULT_TEX0) << R200_VPI_OUT_REG_INDEX_SHIFT)
+      case VARYING_SLOT_TEX0:
+      case VARYING_SLOT_TEX1:
+      case VARYING_SLOT_TEX2:
+      case VARYING_SLOT_TEX3:
+      case VARYING_SLOT_TEX4:
+      case VARYING_SLOT_TEX5:
+        return (((dst->Index - VARYING_SLOT_TEX0) << R200_VPI_OUT_REG_INDEX_SHIFT)
            | R200_VSF_OUT_CLASS_RESULT_TEXC);
-      case VERT_RESULT_PSIZ:
+      case VARYING_SLOT_PSIZ:
         return R200_VSF_OUT_CLASS_RESULT_POINTSIZE;
       default:
-        fprintf(stderr, "problem in %s, unknown dst output reg %d\n", __FUNCTION__, dst->Index);
+        fprintf(stderr, "problem in %s, unknown dst output reg %d\n", __func__, dst->Index);
         exit(0);
         return 0;
       }
@@ -196,7 +198,7 @@ static unsigned long t_dst(struct prog_dst_register *dst)
       assert (dst->Index == 0);
       return R200_VSF_OUT_CLASS_ADDR;
    default:
-      fprintf(stderr, "problem in %s, unknown register type %d\n", __FUNCTION__, dst->File);
+      fprintf(stderr, "problem in %s, unknown register type %d\n", __func__, dst->File);
       exit(0);
       return 0;
    }
@@ -212,24 +214,20 @@ static unsigned long t_src_class(gl_register_file file)
    case PROGRAM_INPUT:
       return VSF_IN_CLASS_ATTR;
 
-   case PROGRAM_LOCAL_PARAM:
-   case PROGRAM_ENV_PARAM:
-   case PROGRAM_NAMED_PARAM:
    case PROGRAM_CONSTANT:
    case PROGRAM_STATE_VAR:
       return VSF_IN_CLASS_PARAM;
    /*
    case PROGRAM_OUTPUT:
-   case PROGRAM_WRITE_ONLY:
    case PROGRAM_ADDRESS:
    */
    default:
-      fprintf(stderr, "problem in %s", __FUNCTION__);
+      fprintf(stderr, "problem in %s", __func__);
       exit(0);
    }
 }
 
-static INLINE unsigned long t_swizzle(GLubyte swizzle)
+static inline unsigned long t_swizzle(GLubyte swizzle)
 {
 /* this is in fact a NOP as the Mesa SWIZZLE_* are all identical to VSF_IN_COMPONENT_* */
    return swizzle;
@@ -241,7 +239,7 @@ static void vp_dump_inputs(struct r200_vertex_program *vp, char *caller)
    int i;
 
    if(vp == NULL){
-      fprintf(stderr, "vp null in call to %s from %s\n", __FUNCTION__, caller);
+      fprintf(stderr, "vp null in call to %s from %s\n", __func__, caller);
       return ;
    }
 
@@ -269,7 +267,7 @@ static unsigned long t_src_index(struct r200_vertex_program *vp, struct prog_src
 
       vp->inputs[src->Index] = max_reg+1;*/
 
-      //vp_dump_inputs(vp, __FUNCTION__);      
+      //vp_dump_inputs(vp, __func__);  
       assert(vp->inputs[src->Index] != -1);
       return vp->inputs[src->Index];
    } else {
@@ -331,7 +329,7 @@ static unsigned long t_opcode(enum prog_opcode opcode)
    case OPCODE_SLT: return R200_VPI_OUT_OP_SLT;
 
    default: 
-      fprintf(stderr, "%s: Should not be called with opcode %d!", __FUNCTION__, opcode);
+      fprintf(stderr, "%s: Should not be called with opcode %d!", __func__, opcode);
    }
    exit(-1);
    return 0;
@@ -356,7 +354,7 @@ static unsigned long op_operands(enum prog_opcode opcode)
                       ((t_src_class(a.File) == VSF_IN_CLASS_PARAM && \
                         t_src_class(b.File) == VSF_IN_CLASS_PARAM) || \
                        (t_src_class(a.File) == VSF_IN_CLASS_ATTR && \
-                        t_src_class(b.File) == VSF_IN_CLASS_ATTR))) \
+                        t_src_class(b.File) == VSF_IN_CLASS_ATTR)))
 
 /* fglrx on rv250 codes up unused sources as follows:
    unused but necessary sources are same as previous source, zero-ed out.
@@ -396,9 +394,9 @@ static unsigned long op_operands(enum prog_opcode opcode)
  *
  * \return  GL_TRUE for success, GL_FALSE for failure.
  */
-static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_vertex_program *vp)
+static GLboolean r200_translate_vertex_program(struct gl_context *ctx, struct r200_vertex_program *vp)
 {
-   struct gl_vertex_program *mesa_vp = &vp->mesa_program;
+   struct gl_program *mesa_vp = &vp->mesa_program;
    struct prog_instruction *vpi;
    int i;
    VERTEX_SHADER_INSTRUCTION *o_inst;
@@ -415,39 +413,34 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
    vp->translated = GL_TRUE;
    vp->fogmode = ctx->Fog.Mode;
 
-   if (mesa_vp->Base.NumInstructions == 0)
+   if (mesa_vp->arb.NumInstructions == 0)
       return GL_FALSE;
 
 #if 0
-   if ((mesa_vp->Base.InputsRead &
+   if ((mesa_vp->info.inputs_read &
       ~(VERT_BIT_POS | VERT_BIT_NORMAL | VERT_BIT_COLOR0 | VERT_BIT_COLOR1 |
       VERT_BIT_FOG | VERT_BIT_TEX0 | VERT_BIT_TEX1 | VERT_BIT_TEX2 |
       VERT_BIT_TEX3 | VERT_BIT_TEX4 | VERT_BIT_TEX5)) != 0) {
-      if (R200_DEBUG & DEBUG_FALLBACKS) {
+      if (R200_DEBUG & RADEON_FALLBACKS) {
         fprintf(stderr, "can't handle vert prog inputs 0x%x\n",
-           mesa_vp->Base.InputsRead);
+           mesa_vp->info.inputs_read);
       }
       return GL_FALSE;
    }
 #endif
 
-   if ((mesa_vp->Base.OutputsWritten &
-      ~((1 << VERT_RESULT_HPOS) | (1 << VERT_RESULT_COL0) | (1 << VERT_RESULT_COL1) |
-      (1 << VERT_RESULT_FOGC) | (1 << VERT_RESULT_TEX0) | (1 << VERT_RESULT_TEX1) |
-      (1 << VERT_RESULT_TEX2) | (1 << VERT_RESULT_TEX3) | (1 << VERT_RESULT_TEX4) |
-      (1 << VERT_RESULT_TEX5) | (1 << VERT_RESULT_PSIZ))) != 0) {
-      if (R200_DEBUG & DEBUG_FALLBACKS) {
-        fprintf(stderr, "can't handle vert prog outputs 0x%x\n",
-           mesa_vp->Base.OutputsWritten);
+   if ((mesa_vp->info.outputs_written &
+      ~((1 << VARYING_SLOT_POS) | (1 << VARYING_SLOT_COL0) | (1 << VARYING_SLOT_COL1) |
+      (1 << VARYING_SLOT_FOGC) | (1 << VARYING_SLOT_TEX0) | (1 << VARYING_SLOT_TEX1) |
+      (1 << VARYING_SLOT_TEX2) | (1 << VARYING_SLOT_TEX3) | (1 << VARYING_SLOT_TEX4) |
+      (1 << VARYING_SLOT_TEX5) | (1 << VARYING_SLOT_PSIZ))) != 0) {
+      if (R200_DEBUG & RADEON_FALLBACKS) {
+        fprintf(stderr, "can't handle vert prog outputs 0x%llx\n",
+                 (unsigned long long) mesa_vp->info.outputs_written);
       }
       return GL_FALSE;
    }
 
-   if (mesa_vp->IsNVProgram) {
-   /* subtle differences in spec like guaranteed initialized regs could cause
-      headaches. Might want to remove the driconf option to enable it completely */
-      return GL_FALSE;
-   }
    /* Initial value should be last tmp reg that hw supports.
       Strangely enough r300 doesnt mind even though these would be out of range.
       Smart enough to realize that it doesnt need it? */
@@ -456,27 +449,28 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
    struct prog_dst_register dst;
 
 /* FIXME: is changing the prog safe to do here? */
-   if (mesa_vp->IsPositionInvariant &&
+   if (mesa_vp->arb.IsPositionInvariant &&
       /* make sure we only do this once */
-       !(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) {
+       !(mesa_vp->info.outputs_written & (1 << VARYING_SLOT_POS))) {
         _mesa_insert_mvp_code(ctx, mesa_vp);
       }
 
    /* for fogc, can't change mesa_vp, as it would hose swtnl, and exp with
       base e isn't directly available neither. */
-   if ((mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_FOGC)) && !vp->fogpidx) {
+   if ((mesa_vp->info.outputs_written & (1 << VARYING_SLOT_FOGC)) &&
+       !vp->fogpidx) {
       struct gl_program_parameter_list *paramList;
-      gl_state_index tokens[STATE_LENGTH] = { STATE_FOG_PARAMS, 0, 0, 0, 0 };
-      paramList = mesa_vp->Base.Parameters;
+      gl_state_index16 tokens[STATE_LENGTH] = { STATE_FOG_PARAMS, 0, 0, 0, 0 };
+      paramList = mesa_vp->Parameters;
       vp->fogpidx = _mesa_add_state_reference(paramList, tokens);
    }
 
    vp->pos_end = 0;
-   mesa_vp->Base.NumNativeInstructions = 0;
-   if (mesa_vp->Base.Parameters)
-      mesa_vp->Base.NumNativeParameters = mesa_vp->Base.Parameters->NumParameters;
+   mesa_vp->arb.NumNativeInstructions = 0;
+   if (mesa_vp->Parameters)
+      mesa_vp->arb.NumNativeParameters = mesa_vp->Parameters->NumParameters;
    else
-      mesa_vp->Base.NumNativeParameters = 0;
+      mesa_vp->arb.NumNativeParameters = 0;
 
    for(i = 0; i < VERT_ATTRIB_MAX; i++)
       vp->inputs[i] = -1;
@@ -502,56 +496,60 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
    Haven't seen attr 14 used, maybe that's for the hw pointsize vec1 (which is
    not possibe to use with vertex progs as it is lacking in vert prog specification) */
 /* may look different when using idx buf / input_route instead of se_vtx_fmt? */
-   if (mesa_vp->Base.InputsRead & VERT_BIT_POS) {
+   if (mesa_vp->info.inputs_read & VERT_BIT_POS) {
       vp->inputs[VERT_ATTRIB_POS] = 0;
       vp->inputmap_rev[0] = VERT_ATTRIB_POS;
       free_inputs &= ~(1 << 0);
       array_count++;
    }
-   if (mesa_vp->Base.InputsRead & VERT_BIT_WEIGHT) {
-      vp->inputs[VERT_ATTRIB_WEIGHT] = 12;
-      vp->inputmap_rev[1] = VERT_ATTRIB_WEIGHT;
-      array_count++;
-   }
-   if (mesa_vp->Base.InputsRead & VERT_BIT_NORMAL) {
+   if (mesa_vp->info.inputs_read & VERT_BIT_NORMAL) {
       vp->inputs[VERT_ATTRIB_NORMAL] = 1;
       vp->inputmap_rev[2] = VERT_ATTRIB_NORMAL;
       array_count++;
    }
-   if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR0) {
+   if (mesa_vp->info.inputs_read & VERT_BIT_COLOR0) {
       vp->inputs[VERT_ATTRIB_COLOR0] = 2;
       vp->inputmap_rev[4] = VERT_ATTRIB_COLOR0;
       free_inputs &= ~(1 << 2);
       array_count++;
    }
-   if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR1) {
+   if (mesa_vp->info.inputs_read & VERT_BIT_COLOR1) {
       vp->inputs[VERT_ATTRIB_COLOR1] = 3;
       vp->inputmap_rev[5] = VERT_ATTRIB_COLOR1;
       free_inputs &= ~(1 << 3);
       array_count++;
    }
-   if (mesa_vp->Base.InputsRead & VERT_BIT_FOG) {
+   if (mesa_vp->info.inputs_read & VERT_BIT_FOG) {
       vp->inputs[VERT_ATTRIB_FOG] = 15; array_count++;
       vp->inputmap_rev[3] = VERT_ATTRIB_FOG;
       array_count++;
    }
-   for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX5; i++) {
-      if (mesa_vp->Base.InputsRead & (1 << i)) {
-        vp->inputs[i] = i - VERT_ATTRIB_TEX0 + 6;
-        vp->inputmap_rev[8 + i - VERT_ATTRIB_TEX0] = i;
-        free_inputs &= ~(1 << (i - VERT_ATTRIB_TEX0 + 6));
+   /* VERT_ATTRIB_TEX0-5 */
+   for (i = 0; i <= 5; i++) {
+      if (mesa_vp->info.inputs_read & VERT_BIT_TEX(i)) {
+        vp->inputs[VERT_ATTRIB_TEX(i)] = i + 6;
+        vp->inputmap_rev[8 + i] = VERT_ATTRIB_TEX(i);
+        free_inputs &= ~(1 << (i + 6));
         array_count++;
       }
    }
    /* using VERT_ATTRIB_TEX6/7 would be illegal */
+   for (; i < VERT_ATTRIB_TEX_MAX; i++) {
+      if (mesa_vp->info.inputs_read & VERT_BIT_TEX(i)) {
+          if (R200_DEBUG & RADEON_FALLBACKS) {
+              fprintf(stderr, "texture attribute %d in vert prog\n", i);
+          }
+          return GL_FALSE;
+      }
+   }
    /* completely ignore aliasing? */
-   for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) {
+   for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) {
       int j;
    /* completely ignore aliasing? */
-      if (mesa_vp->Base.InputsRead & (1 << i)) {
+      if (mesa_vp->info.inputs_read & VERT_BIT_GENERIC(i)) {
         array_count++;
         if (array_count > 12) {
-           if (R200_DEBUG & DEBUG_FALLBACKS) {
+           if (R200_DEBUG & RADEON_FALLBACKS) {
               fprintf(stderr, "more than 12 attribs used in vert prog\n");
            }
            return GL_FALSE;
@@ -560,31 +558,38 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
            /* will always find one due to limited array_count */
            if (free_inputs & (1 << j)) {
               free_inputs &= ~(1 << j);
-              vp->inputs[i] = j;
-              if (j == 0) vp->inputmap_rev[j] = i; /* mapped to pos */
-              else if (j < 12) vp->inputmap_rev[j + 2] = i; /* mapped to col/tex */
-              else vp->inputmap_rev[j + 1] = i; /* mapped to pos1 */
+              vp->inputs[VERT_ATTRIB_GENERIC(i)] = j;
+              if (j == 0) {
+                  /* mapped to pos */
+                  vp->inputmap_rev[j] = VERT_ATTRIB_GENERIC(i);
+              } else if (j < 12) {
+                  /* mapped to col/tex */
+                  vp->inputmap_rev[j + 2] = VERT_ATTRIB_GENERIC(i);
+              } else {
+                  /* mapped to pos1 */
+                  vp->inputmap_rev[j + 1] = VERT_ATTRIB_GENERIC(i);
+               }
               break;
            }
         }
       }
    }
 
-   if (!(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) {
-      if (R200_DEBUG & DEBUG_FALLBACKS) {
+   if (!(mesa_vp->info.outputs_written & (1 << VARYING_SLOT_POS))) {
+      if (R200_DEBUG & RADEON_FALLBACKS) {
         fprintf(stderr, "can't handle vert prog without position output\n");
       }
       return GL_FALSE;
    }
    if (free_inputs & 1) {
-      if (R200_DEBUG & DEBUG_FALLBACKS) {
+      if (R200_DEBUG & RADEON_FALLBACKS) {
         fprintf(stderr, "can't handle vert prog without position input\n");
       }
       return GL_FALSE;
    }
 
    o_inst = vp->instr;
-   for (vpi = mesa_vp->Base.Instructions; vpi->Opcode != OPCODE_END; vpi++, o_inst++){
+   for (vpi = mesa_vp->arb.Instructions; vpi->Opcode != OPCODE_END; vpi++, o_inst++){
       operands = op_operands(vpi->Opcode);
       are_srcs_scalar = operands & SCALAR_FLAG;
       operands &= OP_MASK;
@@ -676,7 +681,7 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
 
       dst = vpi->DstReg;
       if (dst.File == PROGRAM_OUTPUT &&
-         dst.Index == VERT_RESULT_FOGC &&
+         dst.Index == VARYING_SLOT_FOGC &&
          dst.WriteMask & WRITEMASK_X) {
          fog_temp_i = u_temp_i;
          dst.File = PROGRAM_TEMPORARY;
@@ -1064,21 +1069,21 @@ else {
       }
 
       u_temp_used = (R200_VSF_MAX_TEMPS - 1) - u_temp_i;
-      if (mesa_vp->Base.NumNativeTemporaries <
-        (mesa_vp->Base.NumTemporaries + u_temp_used)) {
-        mesa_vp->Base.NumNativeTemporaries =
-           mesa_vp->Base.NumTemporaries + u_temp_used;
+      if (mesa_vp->arb.NumNativeTemporaries <
+          (mesa_vp->arb.NumTemporaries + u_temp_used)) {
+         mesa_vp->arb.NumNativeTemporaries =
+            mesa_vp->arb.NumTemporaries + u_temp_used;
       }
-      if ((mesa_vp->Base.NumTemporaries + u_temp_used) > R200_VSF_MAX_TEMPS) {
-        if (R200_DEBUG & DEBUG_FALLBACKS) {
-           fprintf(stderr, "Ran out of temps, num temps %d, us %d\n", mesa_vp->Base.NumTemporaries, u_temp_used);
+      if ((mesa_vp->arb.NumTemporaries + u_temp_used) > R200_VSF_MAX_TEMPS) {
+        if (R200_DEBUG & RADEON_FALLBACKS) {
+            fprintf(stderr, "Ran out of temps, num temps %d, us %d\n", mesa_vp->arb.NumTemporaries, u_temp_used);
         }
         return GL_FALSE;
       }
       u_temp_i = R200_VSF_MAX_TEMPS - 1;
       if(o_inst - vp->instr >= R200_VSF_MAX_INST) {
-        mesa_vp->Base.NumNativeInstructions = 129;
-        if (R200_DEBUG & DEBUG_FALLBACKS) {
+         mesa_vp->arb.NumNativeInstructions = 129;
+        if (R200_DEBUG & RADEON_FALLBACKS) {
            fprintf(stderr, "more than 128 native instructions\n");
         }
         return GL_FALSE;
@@ -1089,7 +1094,7 @@ else {
    }
 
    vp->native = GL_TRUE;
-   mesa_vp->Base.NumNativeInstructions = (o_inst - vp->instr);
+   mesa_vp->arb.NumNativeInstructions = (o_inst - vp->instr);
 #if 0
    fprintf(stderr, "hw program:\n");
    for(i=0; i < vp->program.length; i++)
@@ -1098,7 +1103,7 @@ else {
    return GL_TRUE;
 }
 
-void r200SetupVertexProg( GLcontext *ctx ) {
+void r200SetupVertexProg( struct gl_context *ctx ) {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    struct r200_vertex_program *vp = (struct r200_vertex_program *)ctx->VertexProgram.Current;
    GLboolean fallback;
@@ -1109,8 +1114,7 @@ void r200SetupVertexProg( GLcontext *ctx ) {
       r200_translate_vertex_program(ctx, vp);
    }
    /* could optimize setting up vertex progs away for non-tcl hw */
-   fallback = !(vp->native && r200VertexProgUpdateParams(ctx, vp) &&
-      rmesa->radeon.radeonScreen->drmSupportsVertexProgram);
+   fallback = !(vp->native && r200VertexProgUpdateParams(ctx, vp));
    TCL_FALLBACK(ctx, R200_TCL_FALLBACK_VERTEX_PROGRAM, fallback);
    if (rmesa->radeon.TclFallback) return;
 
@@ -1122,15 +1126,15 @@ void r200SetupVertexProg( GLcontext *ctx ) {
    R200_STATECHANGE( rmesa, pvs );
 
    rmesa->hw.pvs.cmd[PVS_CNTL_1] = (0 << R200_PVS_CNTL_1_PROGRAM_START_SHIFT) |
-      ((vp->mesa_program.Base.NumNativeInstructions - 1) << R200_PVS_CNTL_1_PROGRAM_END_SHIFT) |
+      ((vp->mesa_program.arb.NumNativeInstructions - 1) << R200_PVS_CNTL_1_PROGRAM_END_SHIFT) |
       (vp->pos_end << R200_PVS_CNTL_1_POS_END_SHIFT);
    rmesa->hw.pvs.cmd[PVS_CNTL_2] = (0 << R200_PVS_CNTL_2_PARAM_OFFSET_SHIFT) |
-      (vp->mesa_program.Base.NumNativeParameters << R200_PVS_CNTL_2_PARAM_COUNT_SHIFT);
+      (vp->mesa_program.arb.NumNativeParameters << R200_PVS_CNTL_2_PARAM_COUNT_SHIFT);
 
    /* maybe user clip planes just work with vertex progs... untested */
    if (ctx->Transform.ClipPlanesEnabled) {
       R200_STATECHANGE( rmesa, tcl );
-      if (vp->mesa_program.IsPositionInvariant) {
+      if (vp->mesa_program.arb.IsPositionInvariant) {
         rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (ctx->Transform.ClipPlanesEnabled << 2);
       }
       else {
@@ -1139,7 +1143,7 @@ void r200SetupVertexProg( GLcontext *ctx ) {
    }
 
    if (vp != rmesa->curr_vp_hw) {
-      GLuint count = vp->mesa_program.Base.NumNativeInstructions;
+      GLuint count = vp->mesa_program.arb.NumNativeInstructions;
       drm_radeon_cmd_header_t tmp;
 
       R200_STATECHANGE( rmesa, vpi[0] );
@@ -1178,48 +1182,35 @@ void r200SetupVertexProg( GLcontext *ctx ) {
 }
 
 
-static void
-r200BindProgram(GLcontext *ctx, GLenum target, struct gl_program *prog)
-{
-   r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
-   switch(target){
-   case GL_VERTEX_PROGRAM_ARB:
-      rmesa->curr_vp_hw = NULL;
-      break;
-   default:
-      _mesa_problem(ctx, "Target not supported yet!");
-      break;
-   }
-}
-
 static struct gl_program *
-r200NewProgram(GLcontext *ctx, GLenum target, GLuint id)
+r200NewProgram(struct gl_context *ctx, GLenum target, GLuint id,
+               bool is_arb_asm)
 {
-   struct r200_vertex_program *vp;
-
    switch(target){
-   case GL_VERTEX_PROGRAM_ARB:
-      vp = CALLOC_STRUCT(r200_vertex_program);
-      return _mesa_init_vertex_program(ctx, &vp->mesa_program, target, id);
-   case GL_FRAGMENT_PROGRAM_ARB:
-   case GL_FRAGMENT_PROGRAM_NV:
-      return _mesa_init_fragment_program( ctx, CALLOC_STRUCT(gl_fragment_program), target, id );
+   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_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;
    }
-   return NULL;        
 }
 
 
 static void
-r200DeleteProgram(GLcontext *ctx, struct gl_program *prog)
+r200DeleteProgram(struct gl_context *ctx, struct gl_program *prog)
 {
    _mesa_delete_program(ctx, prog);
 }
 
-static void
-r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog)
+static GLboolean
+r200ProgramStringNotify(struct gl_context *ctx, GLenum target, struct gl_program *prog)
 {
    struct r200_vertex_program *vp = (void *)prog;
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
@@ -1228,7 +1219,7 @@ r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog)
    case GL_VERTEX_PROGRAM_ARB:
       vp->translated = GL_FALSE;
       vp->fogpidx = 0;
-/*      memset(&vp->translated, 0, sizeof(struct r200_vertex_program) - sizeof(struct gl_vertex_program));*/
+/*      memset(&vp->translated, 0, sizeof(struct r200_vertex_program) - sizeof(struct gl_program));*/
       r200_translate_vertex_program(ctx, vp);
       rmesa->curr_vp_hw = NULL;
       break;
@@ -1237,16 +1228,18 @@ r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog)
       break;
    }
    /* need this for tcl fallbacks */
-   _tnl_program_string(ctx, target, prog);
+   (void) _tnl_program_string(ctx, target, prog);
+
+   /* XXX check if program is legal, within limits */
+   return GL_TRUE;
 }
 
 static GLboolean
-r200IsProgramNative(GLcontext *ctx, GLenum target, struct gl_program *prog)
+r200IsProgramNative(struct gl_context *ctx, GLenum target, struct gl_program *prog)
 {
    struct r200_vertex_program *vp = (void *)prog;
 
    switch(target){
-   case GL_VERTEX_STATE_PROGRAM_NV:
    case GL_VERTEX_PROGRAM_ARB:
       if (!vp->translated) {
         r200_translate_vertex_program(ctx, vp);
@@ -1262,7 +1255,6 @@ r200IsProgramNative(GLcontext *ctx, GLenum target, struct gl_program *prog)
 void r200InitShaderFuncs(struct dd_function_table *functions)
 {
    functions->NewProgram = r200NewProgram;
-   functions->BindProgram = r200BindProgram;
    functions->DeleteProgram = r200DeleteProgram;
    functions->ProgramStringNotify = r200ProgramStringNotify;
    functions->IsProgramNative = r200IsProgramNative;