[Mesa-dev] [PATCH 20/25] mesa/r200/i915/i965: eliminate gl_fragment_program and use new shared shader_info

Timothy Arceri timothy.arceri at collabora.com
Tue Oct 18 06:12:23 UTC 2016


---
 src/compiler/glsl/glsl_to_nir.cpp                |  6 ---
 src/compiler/glsl/ir_set_program_inouts.cpp      | 14 ++----
 src/compiler/shader_enums.h                      |  5 +-
 src/mesa/drivers/common/meta.c                   | 10 ++--
 src/mesa/drivers/common/meta.h                   |  2 +-
 src/mesa/drivers/dri/i915/i915_context.h         |  2 +-
 src/mesa/drivers/dri/i915/i915_fragprog.c        | 40 +++++++--------
 src/mesa/drivers/dri/i915/i915_program.c         | 16 +++---
 src/mesa/drivers/dri/i915/i915_state.c           |  2 +-
 src/mesa/drivers/dri/i915/intel_tris.c           |  4 +-
 src/mesa/drivers/dri/i965/brw_clip.c             |  2 +-
 src/mesa/drivers/dri/i965/brw_context.c          |  2 +-
 src/mesa/drivers/dri/i965/brw_context.h          |  8 +--
 src/mesa/drivers/dri/i965/brw_curbe.c            |  5 +-
 src/mesa/drivers/dri/i965/brw_draw.c             |  2 +-
 src/mesa/drivers/dri/i965/brw_program.c          |  5 +-
 src/mesa/drivers/dri/i965/brw_sf.c               |  4 +-
 src/mesa/drivers/dri/i965/brw_wm.c               | 47 ++++++++---------
 src/mesa/drivers/dri/i965/brw_wm_state.c         |  8 +--
 src/mesa/drivers/dri/i965/brw_wm_surface_state.c |  5 +-
 src/mesa/drivers/dri/i965/gen6_sf_state.c        |  3 +-
 src/mesa/drivers/dri/i965/gen6_wm_state.c        |  2 +-
 src/mesa/drivers/dri/i965/gen8_sf_state.c        |  2 +-
 src/mesa/drivers/dri/r200/r200_vertprog.c        |  4 +-
 src/mesa/main/arbprogram.c                       | 51 +++++++++----------
 src/mesa/main/context.c                          |  8 +--
 src/mesa/main/ffvertex_prog.c                    |  5 +-
 src/mesa/main/mtypes.h                           | 45 +++++++----------
 src/mesa/main/shaderapi.c                        |  3 +-
 src/mesa/main/shared.c                           |  5 +-
 src/mesa/main/state.c                            | 46 ++++++++---------
 src/mesa/main/state.h                            |  2 +-
 src/mesa/main/texstate.c                         |  2 +-
 src/mesa/program/arbprogparse.c                  | 64 ++++++++++++------------
 src/mesa/program/arbprogparse.h                  |  5 +-
 src/mesa/program/ir_to_mesa.cpp                  |  9 ++--
 src/mesa/program/prog_statevars.c                |  8 +--
 src/mesa/program/prog_to_nir.c                   | 13 +----
 src/mesa/program/program.c                       | 21 ++++----
 src/mesa/program/program.h                       | 24 +--------
 src/mesa/program/programopt.c                    | 31 ++++++------
 src/mesa/program/programopt.h                    |  5 +-
 src/mesa/state_tracker/st_atom.c                 |  2 +-
 src/mesa/state_tracker/st_atom_constbuf.c        |  2 +-
 src/mesa/state_tracker/st_atom_rasterizer.c      |  4 +-
 src/mesa/state_tracker/st_atom_sampler.c         |  2 +-
 src/mesa/state_tracker/st_atom_shader.c          |  4 +-
 src/mesa/state_tracker/st_atom_texture.c         |  2 +-
 src/mesa/state_tracker/st_cb_bitmap.c            |  3 +-
 src/mesa/state_tracker/st_cb_bitmap.h            |  2 +-
 src/mesa/state_tracker/st_cb_drawpixels.c        |  6 +--
 src/mesa/state_tracker/st_cb_drawtex.c           |  2 +-
 src/mesa/state_tracker/st_cb_program.c           |  2 +-
 src/mesa/state_tracker/st_context.c              |  2 +-
 src/mesa/state_tracker/st_debug.c                |  4 +-
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp       | 12 ++---
 src/mesa/state_tracker/st_mesa_to_tgsi.c         |  6 +--
 src/mesa/state_tracker/st_program.c              | 47 +++++++++--------
 src/mesa/state_tracker/st_program.h              |  8 +--
 src/mesa/swrast/s_context.c                      | 15 +++---
 src/mesa/swrast/s_fragprog.c                     | 23 ++++-----
 src/mesa/swrast/s_span.c                         |  4 +-
 src/mesa/tnl/t_context.c                         |  8 +--
 63 files changed, 306 insertions(+), 401 deletions(-)

diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp
index a2284e2..42e9e96 100644
--- a/src/compiler/glsl/glsl_to_nir.cpp
+++ b/src/compiler/glsl/glsl_to_nir.cpp
@@ -181,13 +181,7 @@ glsl_to_nir(const struct gl_shader_program *shader_prog,
       break;
 
    case MESA_SHADER_FRAGMENT: {
-      struct gl_fragment_program *fp =
-         (struct gl_fragment_program *)sh->Program;
-
-      shader->info->fs.uses_discard = fp->UsesKill;
-      shader->info->fs.uses_sample_qualifier = fp->IsSample;
       shader->info->fs.early_fragment_tests = sh->info.EarlyFragmentTests;
-      shader->info->fs.depth_layout = fp->FragDepthLayout;
       break;
    }
 
diff --git a/src/compiler/glsl/ir_set_program_inouts.cpp b/src/compiler/glsl/ir_set_program_inouts.cpp
index a177219..e68ecfb 100644
--- a/src/compiler/glsl/ir_set_program_inouts.cpp
+++ b/src/compiler/glsl/ir_set_program_inouts.cpp
@@ -26,8 +26,6 @@
  *
  * Sets the InputsRead and OutputsWritten of Mesa programs.
  *
- * Additionally, for fragment shaders, set the IsSample bitfield.
- *
  * Mesa programs (gl_program, not gl_shader_program) have a set of
  * flags indicating which varyings are read and written.  Computing
  * which are actually read from some sort of backend code can be
@@ -123,9 +121,7 @@ mark(struct gl_program *prog, ir_variable *var, int offset, int len,
             prog->DoubleInputsRead |= bitfield;
 
          if (stage == MESA_SHADER_FRAGMENT) {
-            gl_fragment_program *fprog = (gl_fragment_program *) prog;
-            if (var->data.sample)
-               fprog->IsSample |= bitfield;
+            prog->info.fs.uses_sample_qualifier |= var->data.sample;
          }
       } else if (var->data.mode == ir_var_system_value) {
          prog->SystemValuesRead |= bitfield;
@@ -411,8 +407,7 @@ ir_set_program_inouts_visitor::visit_enter(ir_discard *)
    /* discards are only allowed in fragment shaders. */
    assert(this->shader_stage == MESA_SHADER_FRAGMENT);
 
-   gl_fragment_program *fprog = (gl_fragment_program *) prog;
-   fprog->UsesKill = true;
+   prog->info.fs.uses_discard = true;
 
    return visit_continue;
 }
@@ -439,9 +434,8 @@ do_set_program_inouts(exec_list *instructions, struct gl_program *prog,
    prog->PatchOutputsWritten = 0;
    prog->SystemValuesRead = 0;
    if (shader_stage == MESA_SHADER_FRAGMENT) {
-      gl_fragment_program *fprog = (gl_fragment_program *) prog;
-      fprog->IsSample = 0;
-      fprog->UsesKill = false;
+      prog->info.fs.uses_sample_qualifier = false;
+      prog->info.fs.uses_discard = false;
    }
    visit_list_elements(&v, instructions);
 }
diff --git a/src/compiler/shader_enums.h b/src/compiler/shader_enums.h
index b6e048e..aa97691 100644
--- a/src/compiler/shader_enums.h
+++ b/src/compiler/shader_enums.h
@@ -489,13 +489,10 @@ const char *gl_system_value_name(gl_system_value sysval);
 /**
  * The possible interpolation qualifiers that can be applied to a fragment
  * shader input in GLSL.
- *
- * Note: INTERP_MODE_NONE must be 0 so that memsetting the
- * gl_fragment_program data structure to 0 causes the default behavior.
  */
 enum glsl_interp_mode
 {
-   INTERP_MODE_NONE = 0,
+   INTERP_MODE_NONE,
    INTERP_MODE_SMOOTH,
    INTERP_MODE_FLAT,
    INTERP_MODE_NOPERSPECTIVE,
diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index ab81eed..4a373f0 100644
--- a/src/mesa/drivers/common/meta.c
+++ b/src/mesa/drivers/common/meta.c
@@ -573,8 +573,8 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
 
       if (ctx->Extensions.ARB_fragment_program) {
          save->FragmentProgramEnabled = ctx->FragmentProgram.Enabled;
-         _mesa_reference_fragprog(ctx, &save->FragmentProgram,
-				  ctx->FragmentProgram.Current);
+         _mesa_reference_program(ctx, &save->FragmentProgram,
+                                 ctx->FragmentProgram.Current);
          _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_FALSE);
       }
 
@@ -953,9 +953,9 @@ _mesa_meta_end(struct gl_context *ctx)
       if (ctx->Extensions.ARB_fragment_program) {
          _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB,
                           save->FragmentProgramEnabled);
-         _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
-                                  save->FragmentProgram);
-	 _mesa_reference_fragprog(ctx, &save->FragmentProgram, NULL);
+         _mesa_reference_program(ctx, &ctx->FragmentProgram.Current,
+                                 save->FragmentProgram);
+	 _mesa_reference_program(ctx, &save->FragmentProgram, NULL);
       }
 
       if (ctx->Extensions.ATI_fragment_shader) {
diff --git a/src/mesa/drivers/common/meta.h b/src/mesa/drivers/common/meta.h
index 4d3b8ec..a7018f5 100644
--- a/src/mesa/drivers/common/meta.h
+++ b/src/mesa/drivers/common/meta.h
@@ -123,7 +123,7 @@ struct save_state
    GLboolean VertexProgramEnabled;
    struct gl_program *VertexProgram;
    GLboolean FragmentProgramEnabled;
-   struct gl_fragment_program *FragmentProgram;
+   struct gl_program *FragmentProgram;
    GLboolean ATIFragmentShaderEnabled;
    struct gl_shader_program *Shader[MESA_SHADER_STAGES];
    struct gl_shader_program *ActiveShader;
diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h
index d8f592b..2046d78 100644
--- a/src/mesa/drivers/dri/i915/i915_context.h
+++ b/src/mesa/drivers/dri/i915/i915_context.h
@@ -140,7 +140,7 @@ enum {
  */
 struct i915_fragment_program
 {
-   struct gl_fragment_program FragProg;
+   struct gl_program FragProg;
 
    bool translated;
    bool params_uptodate;
diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c
index 4e1df73..ae23071 100644
--- a/src/mesa/drivers/dri/i915/i915_fragprog.c
+++ b/src/mesa/drivers/dri/i915/i915_fragprog.c
@@ -95,7 +95,7 @@ get_texcoord_mapping(struct i915_fragment_program *p, uint8_t texcoord)
 static GLuint
 src_vector(struct i915_fragment_program *p,
            const struct prog_src_register *source,
-           const struct gl_fragment_program *program)
+           const struct gl_program *program)
 {
    GLuint src;
    unsigned unit;
@@ -186,7 +186,7 @@ src_vector(struct i915_fragment_program *p,
    case PROGRAM_STATE_VAR:
    case PROGRAM_UNIFORM:
       src = i915_emit_param4fv(p,
-	 &program->Base.Parameters->ParameterValues[source->Index][0].f);
+	 &program->Parameters->ParameterValues[source->Index][0].f);
       break;
 
    default:
@@ -278,8 +278,8 @@ translate_tex_src_target(struct i915_fragment_program *p, GLubyte bit)
 #define EMIT_TEX( OP )						\
 do {								\
    GLuint dim = translate_tex_src_target( p, inst->TexSrcTarget );	\
-   const struct gl_fragment_program *program = &p->FragProg;	\
-   GLuint unit = program->Base.SamplerUnits[inst->TexSrcUnit];	\
+   const struct gl_program *program = &p->FragProg;	\
+   GLuint unit = program->SamplerUnits[inst->TexSrcUnit];	\
    GLuint sampler = i915_emit_decl(p, REG_TYPE_S,		\
 				   unit, dim);			\
    GLuint coord = src_vector( p, &inst->SrcReg[0], program);	\
@@ -313,13 +313,13 @@ do {									\
  */
 static bool calc_live_regs( struct i915_fragment_program *p )
 {
-    const struct gl_fragment_program *program = &p->FragProg;
+    const struct gl_program *program = &p->FragProg;
     GLuint regsUsed = ~((1 << I915_MAX_TEMPORARY) - 1);
     uint8_t live_components[I915_MAX_TEMPORARY] = { 0, };
     GLint i;
    
-    for (i = program->Base.NumInstructions - 1; i >= 0; i--) {
-        struct prog_instruction *inst = &program->Base.Instructions[i];
+    for (i = program->NumInstructions - 1; i >= 0; i--) {
+        struct prog_instruction *inst = &program->Instructions[i];
         int opArgs = _mesa_num_inst_src_regs(inst->Opcode);
         int a;
 
@@ -361,8 +361,8 @@ static bool calc_live_regs( struct i915_fragment_program *p )
 static GLuint get_live_regs( struct i915_fragment_program *p, 
                              const struct prog_instruction *inst )
 {
-    const struct gl_fragment_program *program = &p->FragProg;
-    GLuint nr = inst - program->Base.Instructions;
+    const struct gl_program *program = &p->FragProg;
+    GLuint nr = inst - program->Instructions;
 
     return p->usedRegs[nr];
 }
@@ -382,11 +382,11 @@ static GLuint get_live_regs( struct i915_fragment_program *p,
 static void
 upload_program(struct i915_fragment_program *p)
 {
-   const struct gl_fragment_program *program = &p->FragProg;
-   const struct prog_instruction *inst = program->Base.Instructions;
+   const struct gl_program *program = &p->FragProg;
+   const struct prog_instruction *inst = program->Instructions;
 
    if (INTEL_DEBUG & DEBUG_WM)
-      _mesa_print_program(&program->Base);
+      _mesa_print_program(program);
 
    /* Is this a parse-failed program?  Ensure a valid program is
     * loaded, as the flagging of an error isn't sufficient to stop
@@ -402,9 +402,9 @@ upload_program(struct i915_fragment_program *p)
       return;
    }
 
-   if (program->Base.NumInstructions > I915_MAX_INSN) {
+   if (program->NumInstructions > I915_MAX_INSN) {
       i915_program_error(p, "Exceeded max instructions (%d out of %d)",
-			 program->Base.NumInstructions, I915_MAX_INSN);
+			 program->NumInstructions, I915_MAX_INSN);
       return;
    }
 
@@ -1032,7 +1032,7 @@ fixup_depth_write(struct i915_fragment_program *p)
 static void
 check_texcoord_mapping(struct i915_fragment_program *p)
 {
-   GLbitfield64 inputs = p->FragProg.Base.InputsRead;
+   GLbitfield64 inputs = p->FragProg.InputsRead;
    unsigned unit = 0;
 
    for (unsigned i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) {
@@ -1059,7 +1059,7 @@ check_texcoord_mapping(struct i915_fragment_program *p)
 static void
 check_wpos(struct i915_fragment_program *p)
 {
-   GLbitfield64 inputs = p->FragProg.Base.InputsRead;
+   GLbitfield64 inputs = p->FragProg.InputsRead;
    GLint i;
    unsigned unit = 0;
 
@@ -1087,7 +1087,7 @@ translate_program(struct i915_fragment_program *p)
 
    if (INTEL_DEBUG & DEBUG_WM) {
       printf("fp:\n");
-      _mesa_print_program(&p->FragProg.Base);
+      _mesa_print_program(&p->FragProg);
       printf("\n");
    }
 
@@ -1108,7 +1108,7 @@ track_params(struct i915_fragment_program *p)
    GLint i;
 
    if (p->nr_params)
-      _mesa_load_state_parameters(p->ctx, p->FragProg.Base.Parameters);
+      _mesa_load_state_parameters(p->ctx, p->FragProg.Parameters);
 
    for (i = 0; i < p->nr_params; i++) {
       GLint reg = p->param[i].reg;
@@ -1158,7 +1158,7 @@ i915NewProgram(struct gl_context * ctx, GLenum target, GLuint id)
          if (prog) {
             i915_init_program(I915_CONTEXT(ctx), prog);
 
-            return _mesa_init_gl_program(&prog->FragProg.Base, target, id);
+            return _mesa_init_gl_program(&prog->FragProg, target, id);
          }
          else
             return NULL;
@@ -1257,7 +1257,7 @@ i915ValidateFragmentProgram(struct i915_context *i915)
    struct i915_fragment_program *p =
       (struct i915_fragment_program *) ctx->FragmentProgram._Current;
 
-   const GLbitfield64 inputsRead = p->FragProg.Base.InputsRead;
+   const GLbitfield64 inputsRead = p->FragProg.InputsRead;
    GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK;
    GLuint s2 = S2_TEXCOORD_NONE;
    int i, offset = 0;
diff --git a/src/mesa/drivers/dri/i915/i915_program.c b/src/mesa/drivers/dri/i915/i915_program.c
index 64b0b4d..0abc7e2 100644
--- a/src/mesa/drivers/dri/i915/i915_program.c
+++ b/src/mesa/drivers/dri/i915/i915_program.c
@@ -517,18 +517,18 @@ i915_fini_program(struct i915_fragment_program *p)
    }
 
    if (p->error) {
-      p->FragProg.Base.NumNativeInstructions = 0;
-      p->FragProg.Base.NumNativeAluInstructions = 0;
-      p->FragProg.Base.NumNativeTexInstructions = 0;
-      p->FragProg.Base.NumNativeTexIndirections = 0;
+      p->FragProg.NumNativeInstructions = 0;
+      p->FragProg.NumNativeAluInstructions = 0;
+      p->FragProg.NumNativeTexInstructions = 0;
+      p->FragProg.NumNativeTexIndirections = 0;
    }
    else {
-      p->FragProg.Base.NumNativeInstructions = (p->nr_alu_insn +
+      p->FragProg.NumNativeInstructions = (p->nr_alu_insn +
                                                 p->nr_tex_insn +
                                                 p->nr_decl_insn);
-      p->FragProg.Base.NumNativeAluInstructions = p->nr_alu_insn;
-      p->FragProg.Base.NumNativeTexInstructions = p->nr_tex_insn;
-      p->FragProg.Base.NumNativeTexIndirections = p->nr_tex_indirect;
+      p->FragProg.NumNativeAluInstructions = p->nr_alu_insn;
+      p->FragProg.NumNativeTexInstructions = p->nr_tex_insn;
+      p->FragProg.NumNativeTexIndirections = p->nr_tex_indirect;
    }
 
    p->declarations[0] |= program_size + decl_size - 2;
diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c
index 39abe1b..5a0bb3d 100644
--- a/src/mesa/drivers/dri/i915/i915_state.c
+++ b/src/mesa/drivers/dri/i915/i915_state.c
@@ -650,7 +650,7 @@ i915_update_sprite_point_enable(struct gl_context *ctx)
    /* _NEW_PROGRAM */
    struct i915_fragment_program *p =
       (struct i915_fragment_program *) ctx->FragmentProgram._Current;
-   const GLbitfield64 inputsRead = p->FragProg.Base.InputsRead;
+   const GLbitfield64 inputsRead = p->FragProg.InputsRead;
    struct i915_context *i915 = i915_context(ctx);
    GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK;
    GLuint coord_replace_bits = 0x0;
diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c
index a093a0a..683d5a6 100644
--- a/src/mesa/drivers/dri/i915/intel_tris.c
+++ b/src/mesa/drivers/dri/i915/intel_tris.c
@@ -955,8 +955,8 @@ intelChooseRenderState(struct gl_context * ctx)
         ctx->Polygon.OffsetFill) ? DD_TRI_OFFSET : 0) |
       (ctx->Line.StippleFlag ? DD_LINE_STIPPLE : 0) |
       (ctx->Point._Attenuated ? DD_POINT_ATTEN : 0);
-   const struct gl_fragment_program *fprog = ctx->FragmentProgram._Current;
-   bool have_wpos = (fprog && (fprog->Base.InputsRead & VARYING_BIT_POS));
+   const struct gl_program *fprog = ctx->FragmentProgram._Current;
+   bool have_wpos = (fprog && (fprog->InputsRead & VARYING_BIT_POS));
    GLuint index = 0;
 
    if (INTEL_DEBUG & DEBUG_STATE)
diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c
index 06650b6..5b4de58 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.c
+++ b/src/mesa/drivers/dri/i965/brw_clip.c
@@ -149,7 +149,7 @@ brw_upload_clip_prog(struct brw_context *brw)
    /* Populate the key:
     */
 
-   const struct gl_fragment_program *fprog = brw->fragment_program;
+   const struct gl_program *fprog = brw->fragment_program;
    if (fprog) {
       assert(brw->gen < 6);
       struct gen5_fragment_program *p = (struct gen5_fragment_program *) fprog;
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 68f0073..af8ed2c 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -305,7 +305,7 @@ intel_update_state(struct gl_context * ctx, GLuint new_state)
    /* Resolve color buffers for non-coherent framebuffer fetch. */
    if (!ctx->Extensions.MESA_shader_framebuffer_fetch &&
        ctx->FragmentProgram._Current &&
-       ctx->FragmentProgram._Current->Base.nir->info->outputs_read) {
+       ctx->FragmentProgram._Current->info.outputs_read) {
       const struct gl_framebuffer *fb = ctx->DrawBuffer;
 
       for (unsigned i = 0; i < fb->_NumColorDrawBuffers; i++) {
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 519c198..ecbd7d0 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -356,7 +356,7 @@ struct brw_geometry_program {
 
 /** Subclass of Mesa fragment program */
 struct brw_fragment_program {
-   struct gl_fragment_program program;
+   struct gl_program program;
    GLuint id;  /**< serial no. to identify frag progs, never re-used */
 };
 
@@ -996,7 +996,7 @@ struct brw_context
    const struct gl_program *geometry_program;
    const struct gl_program *tess_ctrl_program;
    const struct gl_program *tess_eval_program;
-   const struct gl_fragment_program *fragment_program;
+   const struct gl_program *fragment_program;
    const struct gl_program *compute_program;
 
    /**
@@ -1729,13 +1729,13 @@ brw_geometry_program(struct gl_program *p)
 }
 
 static inline struct brw_fragment_program *
-brw_fragment_program(struct gl_fragment_program *p)
+brw_fragment_program(struct gl_program *p)
 {
    return (struct brw_fragment_program *) p;
 }
 
 static inline const struct brw_fragment_program *
-brw_fragment_program_const(const struct gl_fragment_program *p)
+brw_fragment_program_const(const struct gl_program *p)
 {
    return (const struct brw_fragment_program *) p;
 }
diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c
index f3f5a80..7d58efb 100644
--- a/src/mesa/drivers/dri/i965/brw_curbe.c
+++ b/src/mesa/drivers/dri/i965/brw_curbe.c
@@ -214,7 +214,7 @@ brw_upload_constant_buffer(struct brw_context *brw)
 
    /* fragment shader constants */
    if (brw->curbe.wm_size) {
-      _mesa_load_state_parameters(ctx, brw->fragment_program->Base.Parameters);
+      _mesa_load_state_parameters(ctx, brw->fragment_program->Parameters);
 
       /* BRW_NEW_CURBE_OFFSETS */
       GLuint offset = brw->curbe.wm_start * 16;
@@ -325,8 +325,7 @@ emit:
     * BRW_NEW_FRAGMENT_PROGRAM
     */
    if (brw->gen == 4 && !brw->is_g4x &&
-       (brw->fragment_program->Base.nir->info->inputs_read &
-        (1 << VARYING_SLOT_POS))) {
+       (brw->fragment_program->info.inputs_read & (1 << VARYING_SLOT_POS))) {
       BEGIN_BATCH(2);
       OUT_BATCH(_3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP << 16 | (2 - 2));
       OUT_BATCH(0);
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index a979128..26d0a6a 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -452,7 +452,7 @@ brw_try_draw_prims(struct gl_context *ctx,
     * index.
     */
    brw->wm.base.sampler_count =
-      util_last_bit(ctx->FragmentProgram._Current->Base.SamplersUsed);
+      util_last_bit(ctx->FragmentProgram._Current->SamplersUsed);
    brw->gs.base.sampler_count = ctx->GeometryProgram._Current ?
       util_last_bit(ctx->GeometryProgram._Current->SamplersUsed) : 0;
    brw->tes.base.sampler_count = ctx->TessEvalProgram._Current ?
diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c
index b0920a8..3a91349 100644
--- a/src/mesa/drivers/dri/i965/brw_program.c
+++ b/src/mesa/drivers/dri/i965/brw_program.c
@@ -154,7 +154,7 @@ static struct gl_program *brwNewProgram( struct gl_context *ctx,
       if (prog) {
 	 prog->id = get_new_program_id(brw->screen);
 
-	 return _mesa_init_gl_program(&prog->program.Base, target, id);
+	 return _mesa_init_gl_program(&prog->program, target, id);
       }
       else
 	 return NULL;
@@ -226,8 +226,7 @@ brwProgramStringNotify(struct gl_context *ctx,
 
    switch (target) {
    case GL_FRAGMENT_PROGRAM_ARB: {
-      struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog;
-      struct brw_fragment_program *newFP = brw_fragment_program(fprog);
+      struct brw_fragment_program *newFP = brw_fragment_program(prog);
       const struct brw_fragment_program *curFP =
          brw_fragment_program_const(brw->fragment_program);
 
diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c
index 308b056..6a9f09a 100644
--- a/src/mesa/drivers/dri/i965/brw_sf.c
+++ b/src/mesa/drivers/dri/i965/brw_sf.c
@@ -191,7 +191,7 @@ brw_upload_sf_prog(struct brw_context *brw)
    if (key.do_point_sprite) {
       key.point_sprite_coord_replace = ctx->Point.CoordReplace & 0xff;
    }
-   if (brw->fragment_program->Base.nir->info->inputs_read &
+   if (brw->fragment_program->info.inputs_read &
        BITFIELD64_BIT(VARYING_SLOT_PNTC)) {
       key.do_point_coord = 1;
    }
@@ -203,7 +203,7 @@ brw_upload_sf_prog(struct brw_context *brw)
    if ((ctx->Point.SpriteOrigin == GL_LOWER_LEFT) != render_to_fbo)
       key.sprite_origin_lower_left = true;
 
-   const struct gl_fragment_program *fprog = brw->fragment_program;
+   const struct gl_program *fprog = brw->fragment_program;
    if (fprog) {
       assert(brw->gen < 6);
       struct gen5_fragment_program *p = (struct gen5_fragment_program *) fprog;
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 53b7d9b..851ba10 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -99,14 +99,14 @@ brw_codegen_wm_prog(struct brw_context *brw,
    if (!prog)
       prog_data.base.use_alt_mode = true;
 
-   assign_fs_binding_table_offsets(devinfo, prog,
-                                   &fp->program.Base, key, &prog_data);
+   assign_fs_binding_table_offsets(devinfo, prog, &fp->program, key,
+                                   &prog_data);
 
    /* Allocate the references to the uniforms that will end up in the
     * prog_data associated with the compiled program, and which will be freed
     * by the state cache.
     */
-   int param_count = fp->program.Base.nir->num_uniforms / 4;
+   int param_count = fp->program.nir->num_uniforms / 4;
    if (fs)
       prog_data.base.nr_image_params = fs->base.NumImages;
    /* The backend also sometimes adds params for texture size. */
@@ -121,10 +121,10 @@ brw_codegen_wm_prog(struct brw_context *brw,
    prog_data.base.nr_params = param_count;
 
    if (prog) {
-      brw_nir_setup_glsl_uniforms(fp->program.Base.nir, prog, &fp->program.Base,
+      brw_nir_setup_glsl_uniforms(fp->program.nir, prog, &fp->program,
                                   &prog_data.base, true);
    } else {
-      brw_nir_setup_arb_uniforms(fp->program.Base.nir, &fp->program.Base,
+      brw_nir_setup_arb_uniforms(fp->program.nir, &fp->program,
                                  &prog_data.base);
    }
 
@@ -135,18 +135,18 @@ brw_codegen_wm_prog(struct brw_context *brw,
    }
 
    if (unlikely(INTEL_DEBUG & DEBUG_WM))
-      brw_dump_ir("fragment", prog, fs ? &fs->base : NULL, &fp->program.Base);
+      brw_dump_ir("fragment", prog, fs ? &fs->base : NULL, &fp->program);
 
    int st_index8 = -1, st_index16 = -1;
    if (INTEL_DEBUG & DEBUG_SHADER_TIME) {
-      st_index8 = brw_get_shader_time_index(brw, prog, &fp->program.Base, ST_FS8);
-      st_index16 = brw_get_shader_time_index(brw, prog, &fp->program.Base, ST_FS16);
+      st_index8 = brw_get_shader_time_index(brw, prog, &fp->program, ST_FS8);
+      st_index16 = brw_get_shader_time_index(brw, prog, &fp->program, ST_FS16);
    }
 
    char *error_str = NULL;
    program = brw_compile_fs(brw->screen->compiler, brw, mem_ctx,
-                            key, &prog_data, fp->program.Base.nir,
-                            &fp->program.Base, st_index8, st_index16,
+                            key, &prog_data, fp->program.nir,
+                            &fp->program, st_index8, st_index16,
                             true, brw->use_rep_send, vue_map,
                             &program_size, &error_str);
 
@@ -450,13 +450,11 @@ brw_wm_populate_key(struct brw_context *brw, struct brw_wm_prog_key *key)
     */
    if (brw->gen < 6) {
       /* _NEW_COLOR */
-      if (fp->program.Base.nir->info->fs.uses_discard ||
-          ctx->Color.AlphaEnabled) {
+      if (prog->info.fs.uses_discard || ctx->Color.AlphaEnabled) {
          lookup |= IZ_PS_KILL_ALPHATEST_BIT;
       }
 
-      if (fp->program.Base.nir->info->outputs_written &
-          BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
+      if (prog->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
          lookup |= IZ_PS_COMPUTES_DEPTH_BIT;
       }
 
@@ -545,9 +543,8 @@ brw_wm_populate_key(struct brw_context *brw, struct brw_wm_prog_key *key)
    }
 
    /* BRW_NEW_VUE_MAP_GEOM_OUT */
-   if (brw->gen < 6 ||
-       _mesa_bitcount_64(fp->program.Base.nir->info->inputs_read &
-                         BRW_FS_VARYING_INPUT_MASK) > 16) {
+   if (brw->gen < 6 || _mesa_bitcount_64(prog->info.inputs_read &
+                                         BRW_FS_VARYING_INPUT_MASK) > 16) {
       key->input_slots_valid = brw->vue_map_geom_out.slots_valid;
    }
 
@@ -604,15 +601,14 @@ brw_fs_precompile(struct gl_context *ctx,
    struct brw_context *brw = brw_context(ctx);
    struct brw_wm_prog_key key;
 
-   struct gl_fragment_program *fp = (struct gl_fragment_program *) prog;
-   struct brw_fragment_program *bfp = brw_fragment_program(fp);
+   struct brw_fragment_program *bfp = brw_fragment_program(prog);
 
    memset(&key, 0, sizeof(key));
 
-   uint64_t outputs_written = fp->Base.nir->info->outputs_written;
+   uint64_t outputs_written = prog->info.outputs_written;
 
    if (brw->gen < 6) {
-      if (fp->Base.nir->info->fs.uses_discard)
+      if (prog->info.fs.uses_discard)
          key.iz_lookup |= IZ_PS_KILL_ALPHATEST_BIT;
 
       if (outputs_written & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
@@ -623,13 +619,12 @@ brw_fs_precompile(struct gl_context *ctx,
       key.iz_lookup |= IZ_DEPTH_WRITE_ENABLE_BIT;
    }
 
-   if (brw->gen < 6 || _mesa_bitcount_64(fp->Base.nir->info->inputs_read &
+   if (brw->gen < 6 || _mesa_bitcount_64(prog->info.inputs_read &
                                          BRW_FS_VARYING_INPUT_MASK) > 16) {
-      key.input_slots_valid =
-         fp->Base.nir->info->inputs_read | VARYING_BIT_POS;
+      key.input_slots_valid = prog->info.inputs_read | VARYING_BIT_POS;
    }
 
-   brw_setup_tex_for_precompile(brw, &key.tex, &fp->Base);
+   brw_setup_tex_for_precompile(brw, &key.tex, prog);
 
    key.nr_color_regions = _mesa_bitcount_64(outputs_written &
          ~(BITFIELD64_BIT(FRAG_RESULT_DEPTH) |
@@ -647,7 +642,7 @@ brw_fs_precompile(struct gl_context *ctx,
    struct brw_vue_map vue_map;
    if (brw->gen < 6) {
       brw_compute_vue_map(&brw->screen->devinfo, &vue_map,
-                          fp->Base.nir->info->inputs_read | VARYING_BIT_POS,
+                          prog->info.inputs_read | VARYING_BIT_POS,
                           false);
    }
 
diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c
index ad5e233..6f2ccab 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_state.c
@@ -48,13 +48,13 @@ brw_color_buffer_write_enabled(struct brw_context *brw)
 {
    struct gl_context *ctx = &brw->ctx;
    /* BRW_NEW_FRAGMENT_PROGRAM */
-   const struct gl_fragment_program *fp = brw->fragment_program;
+   const struct gl_program *fp = brw->fragment_program;
    unsigned i;
 
    /* _NEW_BUFFERS */
    for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
       struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i];
-      uint64_t outputs_written = fp->Base.nir->info->outputs_written;
+      uint64_t outputs_written = fp->info.outputs_written;
 
       /* _NEW_COLOR */
       if (rb && (outputs_written & BITFIELD64_BIT(FRAG_RESULT_COLOR) ||
@@ -79,7 +79,7 @@ brw_upload_wm_unit(struct brw_context *brw)
    const struct gen_device_info *devinfo = &brw->screen->devinfo;
    struct gl_context *ctx = &brw->ctx;
    /* BRW_NEW_FRAGMENT_PROGRAM */
-   const struct gl_fragment_program *fp = brw->fragment_program;
+   const struct gl_program *fp = brw->fragment_program;
    /* BRW_NEW_FS_PROG_DATA */
    const struct brw_wm_prog_data *prog_data =
       brw_wm_prog_data(brw->wm.base.prog_data);
@@ -168,7 +168,7 @@ brw_upload_wm_unit(struct brw_context *brw)
 
    /* BRW_NEW_FRAGMENT_PROGRAM */
    wm->wm5.program_uses_depth = prog_data->uses_src_depth;
-   wm->wm5.program_computes_depth = (fp->Base.nir->info->outputs_written &
+   wm->wm5.program_computes_depth = (fp->info.outputs_written &
 				     BITFIELD64_BIT(FRAG_RESULT_DEPTH)) != 0;
    /* _NEW_BUFFERS
     * Override for NULL depthbuffer case, required by the Pixel Shader Computed
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index d2cbf50..667d48c 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -839,7 +839,7 @@ brw_upload_wm_pull_constants(struct brw_context *brw)
 
    _mesa_shader_write_subroutine_indices(&brw->ctx, MESA_SHADER_FRAGMENT);
    /* _NEW_PROGRAM_CONSTANTS */
-   brw_upload_pull_constants(brw, BRW_NEW_SURFACES, &fp->program.Base,
+   brw_upload_pull_constants(brw, BRW_NEW_SURFACES, &fp->program,
                              stage_state, prog_data);
 }
 
@@ -1146,8 +1146,7 @@ update_renderbuffer_read_surfaces(struct brw_context *brw)
 
    /* BRW_NEW_FRAGMENT_PROGRAM */
    if (!ctx->Extensions.MESA_shader_framebuffer_fetch &&
-       brw->fragment_program &&
-       brw->fragment_program->Base.nir->info->outputs_read) {
+       brw->fragment_program && brw->fragment_program->info.outputs_read) {
       /* _NEW_BUFFERS */
       const struct gl_framebuffer *fb = ctx->DrawBuffer;
 
diff --git a/src/mesa/drivers/dri/i965/gen6_sf_state.c b/src/mesa/drivers/dri/i965/gen6_sf_state.c
index 3824e6e..738e4f0 100644
--- a/src/mesa/drivers/dri/i965/gen6_sf_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_sf_state.c
@@ -177,8 +177,7 @@ calculate_attr_overrides(const struct brw_context *brw,
     * - VARYING_SLOT_{PSIZ,LAYER} and VARYING_SLOT_POS on gen6+
     */
 
-   bool fs_needs_vue_header =
-      brw->fragment_program->Base.nir->info->inputs_read &
+   bool fs_needs_vue_header = brw->fragment_program->info.inputs_read &
       (VARYING_BIT_LAYER | VARYING_BIT_VIEWPORT);
 
    *urb_entry_read_offset = fs_needs_vue_header ? 0 : 1;
diff --git a/src/mesa/drivers/dri/i965/gen6_wm_state.c b/src/mesa/drivers/dri/i965/gen6_wm_state.c
index 711e2fd..bd279ec 100644
--- a/src/mesa/drivers/dri/i965/gen6_wm_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_wm_state.c
@@ -49,7 +49,7 @@ gen6_upload_wm_push_constants(struct brw_context *brw)
 
    _mesa_shader_write_subroutine_indices(&brw->ctx, MESA_SHADER_FRAGMENT);
 
-   gen6_upload_push_constants(brw, &fp->program.Base, prog_data,
+   gen6_upload_push_constants(brw, &fp->program, prog_data,
                               stage_state, AUB_TRACE_WM_CONSTANTS);
 
    if (brw->gen >= 7) {
diff --git a/src/mesa/drivers/dri/i965/gen8_sf_state.c b/src/mesa/drivers/dri/i965/gen8_sf_state.c
index 528d835..5d77b39 100644
--- a/src/mesa/drivers/dri/i965/gen8_sf_state.c
+++ b/src/mesa/drivers/dri/i965/gen8_sf_state.c
@@ -95,7 +95,7 @@ upload_sbe(struct brw_context *brw)
       /* prepare the active component dwords */
       int input_index = 0;
       for (int attr = 0; attr < VARYING_SLOT_MAX; attr++) {
-         if (!(brw->fragment_program->Base.nir->info->inputs_read &
+         if (!(brw->fragment_program->info.inputs_read &
                BITFIELD64_BIT(attr))) {
             continue;
          }
diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c
index bf67602..5f1b3b7 100644
--- a/src/mesa/drivers/dri/r200/r200_vertprog.c
+++ b/src/mesa/drivers/dri/r200/r200_vertprog.c
@@ -1206,8 +1206,8 @@ r200NewProgram(struct gl_context *ctx, GLenum target, GLuint id)
       return _mesa_init_gl_program(&vp->mesa_program, target, id);
    }
    case GL_FRAGMENT_PROGRAM_ARB: {
-      struct gl_fragment_program *prog = CALLOC_STRUCT(gl_fragment_program);
-      return _mesa_init_gl_program(&prog->Base, target, id);
+      struct gl_program *prog = CALLOC_STRUCT(gl_program);
+      return _mesa_init_gl_program(prog, target, id);
    }
    default:
       _mesa_problem(ctx, "Bad target in r200NewProgram");
diff --git a/src/mesa/main/arbprogram.c b/src/mesa/main/arbprogram.c
index 0b6f7cb..9c7622a 100644
--- a/src/mesa/main/arbprogram.c
+++ b/src/mesa/main/arbprogram.c
@@ -63,7 +63,7 @@ _mesa_BindProgramARB(GLenum target, GLuint id)
    }
    else if (target == GL_FRAGMENT_PROGRAM_ARB
             && ctx->Extensions.ARB_fragment_program) {
-      curProg = &ctx->FragmentProgram.Current->Base;
+      curProg = ctx->FragmentProgram.Current;
    }
    else {
       _mesa_error(ctx, GL_INVALID_ENUM, "glBindProgramARB(target)");
@@ -81,7 +81,7 @@ _mesa_BindProgramARB(GLenum target, GLuint id)
       if (target == GL_VERTEX_PROGRAM_ARB)
          newProg = ctx->Shared->DefaultVertexProgram;
       else
-         newProg = &ctx->Shared->DefaultFragmentProgram->Base;
+         newProg = ctx->Shared->DefaultFragmentProgram;
    }
    else {
       /* Bind a user program */
@@ -117,8 +117,7 @@ _mesa_BindProgramARB(GLenum target, GLuint id)
       _mesa_reference_program(ctx, &ctx->VertexProgram.Current, newProg);
    }
    else if (target == GL_FRAGMENT_PROGRAM_ARB) {
-      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
-                               gl_fragment_program(newProg));
+      _mesa_reference_program(ctx, &ctx->FragmentProgram.Current, newProg);
    }
 
    /* Never null pointers */
@@ -166,7 +165,7 @@ _mesa_DeleteProgramsARB(GLsizei n, const GLuint *ids)
                break;
             case GL_FRAGMENT_PROGRAM_ARB:
                if (ctx->FragmentProgram.Current &&
-                   ctx->FragmentProgram.Current->Base.Id == ids[i]) {
+                   ctx->FragmentProgram.Current->Id == ids[i]) {
                   /* unbind this currently bound program */
                   _mesa_BindProgramARB(prog->Target, 0);
                }
@@ -261,7 +260,7 @@ get_local_param_pointer(struct gl_context *ctx, const char *func,
    }
    else if (target == GL_FRAGMENT_PROGRAM_ARB
             && ctx->Extensions.ARB_fragment_program) {
-      prog = &(ctx->FragmentProgram.Current->Base);
+      prog = ctx->FragmentProgram.Current;
       maxParams = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams;
    }
    else {
@@ -317,7 +316,7 @@ void GLAPIENTRY
 _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
                        const GLvoid *string)
 {
-   struct gl_program *base;
+   struct gl_program *prog;
    bool failed;
    GET_CURRENT_CONTEXT(ctx);
 
@@ -335,17 +334,13 @@ _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
    }
 
    if (target == GL_VERTEX_PROGRAM_ARB && ctx->Extensions.ARB_vertex_program) {
-      struct gl_program *prog = ctx->VertexProgram.Current;
+      prog = ctx->VertexProgram.Current;
       _mesa_parse_arb_vertex_program(ctx, target, string, len, prog);
-
-      base = prog;
    }
    else if (target == GL_FRAGMENT_PROGRAM_ARB
             && ctx->Extensions.ARB_fragment_program) {
-      struct gl_fragment_program *prog = ctx->FragmentProgram.Current;
+      prog = ctx->FragmentProgram.Current;
       _mesa_parse_arb_fragment_program(ctx, target, string, len, prog);
-
-      base = & prog->Base;
    }
    else {
       _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)");
@@ -356,7 +351,7 @@ _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
 
    if (!failed) {
       /* finally, give the program to the driver for translation/checking */
-      if (!ctx->Driver.ProgramStringNotify(ctx, target, base)) {
+      if (!ctx->Driver.ProgramStringNotify(ctx, target, prog)) {
          failed = true;
          _mesa_error(ctx, GL_INVALID_OPERATION,
                      "glProgramStringARB(rejected by driver");
@@ -368,16 +363,16 @@ _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
          target == GL_FRAGMENT_PROGRAM_ARB ? "fragment" : "vertex";
 
       fprintf(stderr, "ARB_%s_program source for program %d:\n",
-              shader_type, base->Id);
+              shader_type, prog->Id);
       fprintf(stderr, "%s\n", (const char *) string);
 
       if (failed) {
          fprintf(stderr, "ARB_%s_program %d failed to compile.\n",
-                 shader_type, base->Id);
+                 shader_type, prog->Id);
       } else {
          fprintf(stderr, "Mesa IR for ARB_%s_program %d:\n",
-                 shader_type, base->Id);
-         _mesa_print_program(base);
+                 shader_type, prog->Id);
+         _mesa_print_program(prog);
          fprintf(stderr, "\n");
       }
       fflush(stderr);
@@ -392,7 +387,7 @@ _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
          target == GL_FRAGMENT_PROGRAM_ARB ? "fragment" : "vertex";
 
       _mesa_snprintf(filename, sizeof(filename), "%s/%cp-%u.shader_test",
-                     capture_path, shader_type[0], base->Id);
+                     capture_path, shader_type[0], prog->Id);
       file = fopen(filename, "w");
       if (file) {
          fprintf(file,
@@ -661,7 +656,7 @@ _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
    }
    else if (target == GL_FRAGMENT_PROGRAM_ARB
             && ctx->Extensions.ARB_fragment_program) {
-      prog = &(ctx->FragmentProgram.Current->Base);
+      prog = ctx->FragmentProgram.Current;
       limits = &ctx->Const.Program[MESA_SHADER_FRAGMENT];
    }
    else {
@@ -780,25 +775,25 @@ _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
     * The following apply to fragment programs only (at this time)
     */
    if (target == GL_FRAGMENT_PROGRAM_ARB) {
-      const struct gl_fragment_program *fp = ctx->FragmentProgram.Current;
+      const struct gl_program *fp = ctx->FragmentProgram.Current;
       switch (pname) {
          case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
-            *params = fp->Base.NumNativeAluInstructions;
+            *params = fp->NumNativeAluInstructions;
             return;
          case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
-            *params = fp->Base.NumAluInstructions;
+            *params = fp->NumAluInstructions;
             return;
          case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
-            *params = fp->Base.NumTexInstructions;
+            *params = fp->NumTexInstructions;
             return;
          case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
-            *params = fp->Base.NumNativeTexInstructions;
+            *params = fp->NumNativeTexInstructions;
             return;
          case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
-            *params = fp->Base.NumTexIndirections;
+            *params = fp->NumTexIndirections;
             return;
          case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
-            *params = fp->Base.NumNativeTexIndirections;
+            *params = fp->NumNativeTexIndirections;
             return;
          case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
             *params = limits->MaxAluInstructions;
@@ -840,7 +835,7 @@ _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string)
       prog = ctx->VertexProgram.Current;
    }
    else if (target == GL_FRAGMENT_PROGRAM_ARB) {
-      prog = &(ctx->FragmentProgram.Current->Base);
+      prog = ctx->FragmentProgram.Current;
    }
    else {
       _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)");
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 1ae1ab5..44b315e 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -743,7 +743,7 @@ check_context_limits(struct gl_context *ctx)
    assert(VARYING_SLOT_MAX <=
 	  (8 * sizeof(ctx->VertexProgram._Current->OutputsWritten)));
    assert(VARYING_SLOT_MAX <=
-	  (8 * sizeof(ctx->FragmentProgram._Current->Base.InputsRead)));
+	  (8 * sizeof(ctx->FragmentProgram._Current->InputsRead)));
 
    /* shader-related checks */
    assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
@@ -1301,9 +1301,9 @@ _mesa_free_context_data( struct gl_context *ctx )
    _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, NULL);
    _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, NULL);
 
-   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
-   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
-   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
+   _mesa_reference_program(ctx, &ctx->FragmentProgram.Current, NULL);
+   _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, NULL);
+   _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);
 
    _mesa_reference_vao(ctx, &ctx->Array.VAO, NULL);
    _mesa_reference_vao(ctx, &ctx->Array.DefaultVAO, NULL);
diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c
index 15997cc..b318793 100644
--- a/src/mesa/main/ffvertex_prog.c
+++ b/src/mesa/main/ffvertex_prog.c
@@ -148,11 +148,10 @@ static GLboolean check_active_shininess( struct gl_context *ctx,
 
 static void make_state_key( struct gl_context *ctx, struct state_key *key )
 {
-   const struct gl_fragment_program *fp;
+   const struct gl_program *fp = ctx->FragmentProgram._Current;
    GLbitfield mask;
 
    memset(key, 0, sizeof(struct state_key));
-   fp = ctx->FragmentProgram._Current;
 
    /* This now relies on texenvprogram.c being active:
     */
@@ -160,7 +159,7 @@ static void make_state_key( struct gl_context *ctx, struct state_key *key )
 
    key->need_eye_coords = ctx->_NeedEyeCoords;
 
-   key->fragprog_inputs_read = fp->Base.InputsRead;
+   key->fragprog_inputs_read = fp->InputsRead;
    key->varying_vp_inputs = ctx->varying_vp_inputs;
 
    if (ctx->RenderMode == GL_FEEDBACK) {
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 8cc76a4..9e9961b 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1937,13 +1937,19 @@ struct gl_program
 
    GLboolean UsesGather; /**< Does this program use gather4 at all? */
 
-   /**
-    * For vertex and geometry shaders, true if the program uses the
-    * gl_ClipDistance output.  Ignored for fragment shaders.
-    */
-   unsigned ClipDistanceArraySize;
-   unsigned CullDistanceArraySize;
-
+   union {
+      /* Vertex and geometry shaders fields */
+      struct {
+         unsigned ClipDistanceArraySize;
+         unsigned CullDistanceArraySize;
+      };
+
+      /* Fragement shader only fields */
+      struct {
+         GLboolean OriginUpperLeft;
+         GLboolean PixelCenterInteger;
+      };
+   };
 
    /** Named parameters, constants, etc. from program text */
    struct gl_program_parameter_list *Parameters;
@@ -1993,23 +1999,6 @@ struct gl_program
 };
 
 
-/** Fragment program object */
-struct gl_fragment_program
-{
-   struct gl_program Base;   /**< base class */
-   GLboolean UsesKill;          /**< shader uses KIL instruction */
-   GLboolean OriginUpperLeft;
-   GLboolean PixelCenterInteger;
-   enum gl_frag_depth_layout FragDepthLayout;
-
-   /**
-    * Bitfield indicating, for each fragment shader input, 1 if that input
-    * uses sample interpolation, 0 otherwise.  Unused inputs are 0.
-    */
-   GLbitfield64 IsSample;
-};
-
-
 /**
  * State common to vertex and fragment programs.
  */
@@ -2093,13 +2082,13 @@ struct gl_fragment_program_state
 {
    GLboolean Enabled;     /**< User-set fragment program enable flag */
    GLboolean _Enabled;    /**< Enabled and _valid_ user program? */
-   struct gl_fragment_program *Current;  /**< User-bound fragment program */
+   struct gl_program *Current;  /**< User-bound fragment program */
 
    /** Currently enabled and valid fragment program (including internal
     * programs, user-defined fragment programs and GLSL fragment shaders).
     * This is the program we must use when rendering.
     */
-   struct gl_fragment_program *_Current;
+   struct gl_program *_Current;
 
    GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */
 
@@ -2107,7 +2096,7 @@ struct gl_fragment_program_state
    GLboolean _MaintainTexEnvProgram;
 
    /** Program to emulate fixed-function texture env/combine (see above) */
-   struct gl_fragment_program *_TexEnvProgram;
+   struct gl_program *_TexEnvProgram;
 
    /** Cache of fixed-function programs */
    struct gl_program_cache *Cache;
@@ -3061,7 +3050,7 @@ struct gl_shared_state
    /*@{*/
    struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */
    struct gl_program *DefaultVertexProgram;
-   struct gl_fragment_program *DefaultFragmentProgram;
+   struct gl_program *DefaultFragmentProgram;
    /*@}*/
 
    /* GL_ATI_fragment_shader */
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 56b2e6d..7ca8653 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -2197,8 +2197,7 @@ _mesa_copy_linked_program_data(gl_shader_stage type,
       break;
    }
    case MESA_SHADER_FRAGMENT: {
-      struct gl_fragment_program *dst_fp = (struct gl_fragment_program *) dst;
-      dst_fp->FragDepthLayout = src->FragDepthLayout;
+      dst->info.fs.depth_layout = src->FragDepthLayout;
       break;
    }
    case MESA_SHADER_COMPUTE: {
diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c
index 5ff0b69..04e5443 100644
--- a/src/mesa/main/shared.c
+++ b/src/mesa/main/shared.c
@@ -72,8 +72,7 @@ _mesa_alloc_shared_state(struct gl_context *ctx)
    shared->DefaultVertexProgram =
       ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
    shared->DefaultFragmentProgram =
-      gl_fragment_program(ctx->Driver.NewProgram(ctx,
-                                                 GL_FRAGMENT_PROGRAM_ARB, 0));
+      ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
 
    shared->ATIShaders = _mesa_NewHashTable();
    shared->DefaultFragmentShader = _mesa_new_ati_fragment_shader(ctx, 0);
@@ -332,7 +331,7 @@ free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared)
    _mesa_DeleteHashTable(shared->Programs);
 
    _mesa_reference_program(ctx, &shared->DefaultVertexProgram, NULL);
-   _mesa_reference_fragprog(ctx, &shared->DefaultFragmentProgram, NULL);
+   _mesa_reference_program(ctx, &shared->DefaultFragmentProgram, NULL);
 
    _mesa_HashDeleteAll(shared->ATIShaders, delete_fragshader_cb, ctx);
    _mesa_DeleteHashTable(shared->ATIShaders);
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 2f810b4..721f0ef 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -72,7 +72,7 @@ update_program_enables(struct gl_context *ctx)
    ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled
       && ctx->VertexProgram.Current->Instructions;
    ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled
-      && ctx->FragmentProgram.Current->Base.Instructions;
+      && ctx->FragmentProgram.Current->Instructions;
    ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled
       && ctx->ATIFragmentShader.Current->Instructions[0];
 }
@@ -108,7 +108,7 @@ update_program(struct gl_context *ctx)
    const struct gl_shader_program *csProg =
       ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
    const struct gl_program *prevVP = ctx->VertexProgram._Current;
-   const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current;
+   const struct gl_program *prevFP = ctx->FragmentProgram._Current;
    const struct gl_program *prevGP = ctx->GeometryProgram._Current;
    const struct gl_program *prevTCP = ctx->TessCtrlProgram._Current;
    const struct gl_program *prevTEP = ctx->TessEvalProgram._Current;
@@ -138,20 +138,20 @@ update_program(struct gl_context *ctx)
       _mesa_reference_shader_program(ctx,
                                      &ctx->_Shader->_CurrentFragmentProgram,
 				     fsProg);
-      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
-                               gl_fragment_program(fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program));
-      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
-			       NULL);
+      _mesa_reference_program(ctx, &ctx->FragmentProgram._Current,
+                              fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program);
+      _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram,
+                              NULL);
    }
    else if (ctx->FragmentProgram._Enabled) {
       /* Use user-defined fragment program */
       _mesa_reference_shader_program(ctx,
                                      &ctx->_Shader->_CurrentFragmentProgram,
 				     NULL);
-      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
-                               ctx->FragmentProgram.Current);
-      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
-			       NULL);
+      _mesa_reference_program(ctx, &ctx->FragmentProgram._Current,
+                              ctx->FragmentProgram.Current);
+      _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram,
+			      NULL);
    }
    else if (ctx->ATIFragmentShader._Enabled &&
             ctx->ATIFragmentShader.Current->Program) {
@@ -159,10 +159,10 @@ update_program(struct gl_context *ctx)
       _mesa_reference_shader_program(ctx,
                                      &ctx->_Shader->_CurrentFragmentProgram,
                                      NULL);
-      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
-                               gl_fragment_program(ctx->ATIFragmentShader.Current->Program));
-      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
-                               NULL);
+      _mesa_reference_program(ctx, &ctx->FragmentProgram._Current,
+                              ctx->ATIFragmentShader.Current->Program);
+      _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram,
+                              NULL);
    }
    else if (ctx->FragmentProgram._MaintainTexEnvProgram) {
       /* Use fragment program generated from fixed-function state */
@@ -171,16 +171,16 @@ update_program(struct gl_context *ctx)
       _mesa_reference_shader_program(ctx,
                                      &ctx->_Shader->_CurrentFragmentProgram,
 				     f);
-      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
-			       gl_fragment_program(f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program));
-      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
-			       gl_fragment_program(f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program));
+      _mesa_reference_program(ctx, &ctx->FragmentProgram._Current,
+			      f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program);
+      _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram,
+			      f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program);
    }
    else {
       /* No fragment program */
-      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
-      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
-			       NULL);
+      _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, NULL);
+      _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram,
+			      NULL);
    }
 
    if (gsProg && gsProg->LinkStatus
@@ -258,7 +258,7 @@ update_program(struct gl_context *ctx)
       new_state |= _NEW_PROGRAM;
       if (ctx->Driver.BindProgram) {
          ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB,
-                          (struct gl_program *) ctx->FragmentProgram._Current);
+                                 ctx->FragmentProgram._Current);
       }
    }
 
@@ -316,7 +316,7 @@ update_program_constants(struct gl_context *ctx)
 
    if (ctx->FragmentProgram._Current) {
       const struct gl_program_parameter_list *params =
-         ctx->FragmentProgram._Current->Base.Parameters;
+         ctx->FragmentProgram._Current->Parameters;
       if (params && params->StateFlags & ctx->NewState) {
          new_state |= _NEW_PROGRAM_CONSTANTS;
       }
diff --git a/src/mesa/main/state.h b/src/mesa/main/state.h
index 95cde32..8b6f54b 100644
--- a/src/mesa/main/state.h
+++ b/src/mesa/main/state.h
@@ -66,7 +66,7 @@ _mesa_need_secondary_color(const struct gl_context *ctx)
 
    if (ctx->FragmentProgram._Current &&
        (ctx->FragmentProgram._Current != ctx->FragmentProgram._TexEnvProgram) &&
-       (ctx->FragmentProgram._Current->Base.InputsRead & VARYING_BIT_COL1))
+       (ctx->FragmentProgram._Current->InputsRead & VARYING_BIT_COL1))
       return GL_TRUE;
 
    return GL_FALSE;
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
index 94caf2a..95ea5bd 100644
--- a/src/mesa/main/texstate.c
+++ b/src/mesa/main/texstate.c
@@ -705,7 +705,7 @@ update_texture_state( struct gl_context *ctx )
          prog[i] = ctx->_Shader->CurrentProgram[i]->_LinkedShaders[i]->Program;
       } else {
          if (i == MESA_SHADER_FRAGMENT && ctx->FragmentProgram._Enabled)
-            prog[i] = &ctx->FragmentProgram.Current->Base;
+            prog[i] = ctx->FragmentProgram.Current;
          else
             prog[i] = NULL;
       }
diff --git a/src/mesa/program/arbprogparse.c b/src/mesa/program/arbprogparse.c
index 80a0528..51cefe3 100644
--- a/src/mesa/program/arbprogparse.c
+++ b/src/mesa/program/arbprogparse.c
@@ -67,7 +67,7 @@ having three separate program parameter arrays.
 void
 _mesa_parse_arb_fragment_program(struct gl_context* ctx, GLenum target,
                                  const GLvoid *str, GLsizei len,
-                                 struct gl_fragment_program *program)
+                                 struct gl_program *program)
 {
    struct gl_program prog;
    struct asm_parser_state state;
@@ -85,48 +85,48 @@ _mesa_parse_arb_fragment_program(struct gl_context* ctx, GLenum target,
       return;
    }
 
-   free(program->Base.String);
+   free(program->String);
 
    /* Copy the relevant contents of the arb_program struct into the
     * fragment_program struct.
     */
-   program->Base.String          = prog.String;
-   program->Base.NumInstructions = prog.NumInstructions;
-   program->Base.NumTemporaries  = prog.NumTemporaries;
-   program->Base.NumParameters   = prog.NumParameters;
-   program->Base.NumAttributes   = prog.NumAttributes;
-   program->Base.NumAddressRegs  = prog.NumAddressRegs;
-   program->Base.NumNativeInstructions = prog.NumNativeInstructions;
-   program->Base.NumNativeTemporaries = prog.NumNativeTemporaries;
-   program->Base.NumNativeParameters = prog.NumNativeParameters;
-   program->Base.NumNativeAttributes = prog.NumNativeAttributes;
-   program->Base.NumNativeAddressRegs = prog.NumNativeAddressRegs;
-   program->Base.NumAluInstructions   = prog.NumAluInstructions;
-   program->Base.NumTexInstructions   = prog.NumTexInstructions;
-   program->Base.NumTexIndirections   = prog.NumTexIndirections;
-   program->Base.NumNativeAluInstructions = prog.NumAluInstructions;
-   program->Base.NumNativeTexInstructions = prog.NumTexInstructions;
-   program->Base.NumNativeTexIndirections = prog.NumTexIndirections;
-   program->Base.InputsRead      = prog.InputsRead;
-   program->Base.OutputsWritten  = prog.OutputsWritten;
-   program->Base.IndirectRegisterFiles = prog.IndirectRegisterFiles;
+   program->String          = prog.String;
+   program->NumInstructions = prog.NumInstructions;
+   program->NumTemporaries  = prog.NumTemporaries;
+   program->NumParameters   = prog.NumParameters;
+   program->NumAttributes   = prog.NumAttributes;
+   program->NumAddressRegs  = prog.NumAddressRegs;
+   program->NumNativeInstructions = prog.NumNativeInstructions;
+   program->NumNativeTemporaries = prog.NumNativeTemporaries;
+   program->NumNativeParameters = prog.NumNativeParameters;
+   program->NumNativeAttributes = prog.NumNativeAttributes;
+   program->NumNativeAddressRegs = prog.NumNativeAddressRegs;
+   program->NumAluInstructions   = prog.NumAluInstructions;
+   program->NumTexInstructions   = prog.NumTexInstructions;
+   program->NumTexIndirections   = prog.NumTexIndirections;
+   program->NumNativeAluInstructions = prog.NumAluInstructions;
+   program->NumNativeTexInstructions = prog.NumTexInstructions;
+   program->NumNativeTexIndirections = prog.NumTexIndirections;
+   program->InputsRead      = prog.InputsRead;
+   program->OutputsWritten  = prog.OutputsWritten;
+   program->IndirectRegisterFiles = prog.IndirectRegisterFiles;
    for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) {
-      program->Base.TexturesUsed[i] = prog.TexturesUsed[i];
+      program->TexturesUsed[i] = prog.TexturesUsed[i];
       if (prog.TexturesUsed[i])
-         program->Base.SamplersUsed |= (1 << i);
+         program->SamplersUsed |= (1 << i);
    }
-   program->Base.ShadowSamplers = prog.ShadowSamplers;
+   program->ShadowSamplers = prog.ShadowSamplers;
    program->OriginUpperLeft = state.option.OriginUpperLeft;
    program->PixelCenterInteger = state.option.PixelCenterInteger;
 
-   program->UsesKill            = state.fragment.UsesKill;
+   program->info.fs.uses_discard = state.fragment.UsesKill;
 
-   free(program->Base.Instructions);
-   program->Base.Instructions = prog.Instructions;
+   free(program->Instructions);
+   program->Instructions = prog.Instructions;
 
-   if (program->Base.Parameters)
-      _mesa_free_parameter_list(program->Base.Parameters);
-   program->Base.Parameters    = prog.Parameters;
+   if (program->Parameters)
+      _mesa_free_parameter_list(program->Parameters);
+   program->Parameters    = prog.Parameters;
 
    /* Append fog instructions now if the program has "OPTION ARB_fog_exp"
     * or similar.  We used to leave this up to drivers, but it appears
@@ -145,7 +145,7 @@ _mesa_parse_arb_fragment_program(struct gl_context* ctx, GLenum target,
    }
 
 #if DEBUG_FP
-   printf("____________Fragment program %u ________\n", program->Base.Id);
+   printf("____________Fragment program %u ________\n", program->Id);
    _mesa_print_program(&program->Base);
 #endif
 }
diff --git a/src/mesa/program/arbprogparse.h b/src/mesa/program/arbprogparse.h
index 05d93f0..1c39a45 100644
--- a/src/mesa/program/arbprogparse.h
+++ b/src/mesa/program/arbprogparse.h
@@ -29,8 +29,7 @@
 #include "main/glheader.h"
 
 struct gl_context;
-struct gl_fragment_program;
-struct gl_vertex_program;
+struct gl_program;
 
 extern void
 _mesa_parse_arb_vertex_program(struct gl_context *ctx, GLenum target,
@@ -40,6 +39,6 @@ _mesa_parse_arb_vertex_program(struct gl_context *ctx, GLenum target,
 extern void
 _mesa_parse_arb_fragment_program(struct gl_context *ctx, GLenum target,
                                  const GLvoid *str, GLsizei len,
-                                 struct gl_fragment_program *program);
+                                 struct gl_program *program);
 
 #endif
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index debc18d..5e6318b 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -601,10 +601,8 @@ void
 ir_to_mesa_visitor::visit(ir_variable *ir)
 {
    if (strcmp(ir->name, "gl_FragCoord") == 0) {
-      struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog;
-
-      fp->OriginUpperLeft = ir->data.origin_upper_left;
-      fp->PixelCenterInteger = ir->data.pixel_center_integer;
+      this->prog->OriginUpperLeft = ir->data.origin_upper_left;
+      this->prog->PixelCenterInteger = ir->data.pixel_center_integer;
    }
 
    if (ir->data.mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) {
@@ -2926,8 +2924,7 @@ get_mesa_program(struct gl_context *ctx,
 
    /* Set the gl_FragDepth layout. */
    if (target == GL_FRAGMENT_PROGRAM_ARB) {
-      struct gl_fragment_program *fp = (struct gl_fragment_program *)prog;
-      fp->FragDepthLayout = shader_program->FragDepthLayout;
+      prog->info.fs.depth_layout = shader_program->FragDepthLayout;
    }
 
    _mesa_reference_program(ctx, &shader->Program, prog);
diff --git a/src/mesa/program/prog_statevars.c b/src/mesa/program/prog_statevars.c
index 110dfda..f1786e5 100644
--- a/src/mesa/program/prog_statevars.c
+++ b/src/mesa/program/prog_statevars.c
@@ -373,14 +373,14 @@ _mesa_fetch_state(struct gl_context *ctx, const gl_state_index state[],
                COPY_4V(value, ctx->FragmentProgram.Parameters[idx]);
                return;
             case STATE_LOCAL:
-               if (!ctx->FragmentProgram.Current->Base.LocalParams) {
-                  ctx->FragmentProgram.Current->Base.LocalParams =
+               if (!ctx->FragmentProgram.Current->LocalParams) {
+                  ctx->FragmentProgram.Current->LocalParams =
                      calloc(MAX_PROGRAM_LOCAL_PARAMS, sizeof(float[4]));
-                  if (!ctx->FragmentProgram.Current->Base.LocalParams)
+                  if (!ctx->FragmentProgram.Current->LocalParams)
                      return;
                }
 
-               COPY_4V(value, ctx->FragmentProgram.Current->Base.LocalParams[idx]);
+               COPY_4V(value, ctx->FragmentProgram.Current->LocalParams[idx]);
                return;
             default:
                _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()");
diff --git a/src/mesa/program/prog_to_nir.c b/src/mesa/program/prog_to_nir.c
index 981d6f9..b35e6bc 100644
--- a/src/mesa/program/prog_to_nir.c
+++ b/src/mesa/program/prog_to_nir.c
@@ -901,12 +901,9 @@ setup_registers_and_variables(struct ptn_compile *c)
       var->data.index = 0;
 
       if (c->prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
-         struct gl_fragment_program *fp =
-            (struct gl_fragment_program *) c->prog;
-
          if (i == VARYING_SLOT_POS) {
-            var->data.origin_upper_left = fp->OriginUpperLeft;
-            var->data.pixel_center_integer = fp->PixelCenterInteger;
+            var->data.origin_upper_left = c->prog->OriginUpperLeft;
+            var->data.pixel_center_integer = c->prog->PixelCenterInteger;
          } else if (i == VARYING_SLOT_FOGC) {
             /* fogcoord is defined as <f, 0.0, 0.0, 1.0>.  Make the actual
              * input variable a float, and create a local containing the
@@ -1056,12 +1053,6 @@ prog_to_nir(struct gl_program *prog,
    s->info->uses_clip_distance_out = false;
    s->info->separate_shader = false;
 
-   if (stage == MESA_SHADER_FRAGMENT) {
-      struct gl_fragment_program *fp = (struct gl_fragment_program *)prog;
-
-      s->info->fs.uses_discard = fp->UsesKill;
-   }
-
 fail:
    if (c->error) {
       ralloc_free(s);
diff --git a/src/mesa/program/program.c b/src/mesa/program/program.c
index 61cc6fe..4915a09 100644
--- a/src/mesa/program/program.c
+++ b/src/mesa/program/program.c
@@ -93,8 +93,8 @@ _mesa_init_program(struct gl_context *ctx)
    ctx->VertexProgram.Cache = _mesa_new_program_cache();
 
    ctx->FragmentProgram.Enabled = GL_FALSE;
-   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
-                            ctx->Shared->DefaultFragmentProgram);
+   _mesa_reference_program(ctx, &ctx->FragmentProgram.Current,
+                           ctx->Shared->DefaultFragmentProgram);
    assert(ctx->FragmentProgram.Current);
    ctx->FragmentProgram.Cache = _mesa_new_program_cache();
 
@@ -114,7 +114,7 @@ _mesa_free_program_data(struct gl_context *ctx)
 {
    _mesa_reference_program(ctx, &ctx->VertexProgram.Current, NULL);
    _mesa_delete_program_cache(ctx, ctx->VertexProgram.Cache);
-   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
+   _mesa_reference_program(ctx, &ctx->FragmentProgram.Current, NULL);
    _mesa_delete_shader_cache(ctx, ctx->FragmentProgram.Cache);
 
    /* XXX probably move this stuff */
@@ -141,7 +141,7 @@ _mesa_update_default_objects_program(struct gl_context *ctx)
                            ctx->Shared->DefaultVertexProgram);
    assert(ctx->VertexProgram.Current);
 
-   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
+   _mesa_reference_program(ctx, &ctx->FragmentProgram.Current,
                             ctx->Shared->DefaultFragmentProgram);
    assert(ctx->FragmentProgram.Current);
 
@@ -215,14 +215,11 @@ struct gl_program *
 _mesa_new_program(struct gl_context *ctx, GLenum target, GLuint id)
 {
    switch (target) {
-   case GL_FRAGMENT_PROGRAM_ARB: {
-      struct gl_fragment_program *prog = CALLOC_STRUCT(gl_fragment_program);
-      return _mesa_init_gl_program(&prog->Base, target, id);
-   }
    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_COMPUTE_PROGRAM_NV: {
       struct gl_program *prog = CALLOC_STRUCT(gl_program);
       return _mesa_init_gl_program(prog, target, id);
@@ -502,7 +499,7 @@ _mesa_find_free_register(const GLboolean used[],
  */
 GLint
 _mesa_get_min_invocations_per_fragment(struct gl_context *ctx,
-                                       const struct gl_fragment_program *prog,
+                                       const struct gl_program *prog,
                                        bool ignore_sample_qualifier)
 {
    /* From ARB_sample_shading specification:
@@ -521,11 +518,11 @@ _mesa_get_min_invocations_per_fragment(struct gl_context *ctx,
        * "Use of the "sample" qualifier on a fragment shader input
        *  forces per-sample shading"
        */
-      if (prog->IsSample && !ignore_sample_qualifier)
+      if (prog->info.fs.uses_sample_qualifier && !ignore_sample_qualifier)
          return MAX2(_mesa_geometric_samples(ctx->DrawBuffer), 1);
 
-      if (prog->Base.SystemValuesRead & (SYSTEM_BIT_SAMPLE_ID |
-                                         SYSTEM_BIT_SAMPLE_POS))
+      if (prog->SystemValuesRead & (SYSTEM_BIT_SAMPLE_ID |
+                                    SYSTEM_BIT_SAMPLE_POS))
          return MAX2(_mesa_geometric_samples(ctx->DrawBuffer), 1);
       else if (ctx->Multisample.SampleShading)
          return MAX2(ceil(ctx->Multisample.MinSampleShadingValue *
diff --git a/src/mesa/program/program.h b/src/mesa/program/program.h
index defeb2f..6460948 100644
--- a/src/mesa/program/program.h
+++ b/src/mesa/program/program.h
@@ -89,15 +89,6 @@ _mesa_reference_program(struct gl_context *ctx,
       _mesa_reference_program_(ctx, ptr, prog);
 }
 
-static inline void
-_mesa_reference_fragprog(struct gl_context *ctx,
-                         struct gl_fragment_program **ptr,
-                         struct gl_fragment_program *prog)
-{
-   _mesa_reference_program(ctx, (struct gl_program **) ptr,
-                           (struct gl_program *) prog);
-}
-
 extern  GLboolean
 _mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count);
 
@@ -115,7 +106,7 @@ _mesa_find_free_register(const GLboolean used[],
 
 extern GLint
 _mesa_get_min_invocations_per_fragment(struct gl_context *ctx,
-                                       const struct gl_fragment_program *prog,
+                                       const struct gl_program *prog,
                                        bool ignore_sample_qualifier);
 
 static inline GLuint
@@ -165,19 +156,6 @@ _mesa_shader_stage_to_program(unsigned stage)
    return GL_VERTEX_PROGRAM_ARB;
 }
 
-
-static inline struct gl_fragment_program *
-gl_fragment_program(struct gl_program *prog)
-{
-   return (struct gl_fragment_program *) prog;
-}
-
-static inline const struct gl_fragment_program *
-gl_fragment_program_const(const struct gl_program *prog)
-{
-   return (const struct gl_fragment_program *) prog;
-}
-
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/src/mesa/program/programopt.c b/src/mesa/program/programopt.c
index 4610035..f51005d 100644
--- a/src/mesa/program/programopt.c
+++ b/src/mesa/program/programopt.c
@@ -244,16 +244,15 @@ _mesa_insert_mvp_code(struct gl_context *ctx, struct gl_program *vprog)
  * to vertex programs too.
  */
 void
-_mesa_append_fog_code(struct gl_context *ctx,
-		      struct gl_fragment_program *fprog, GLenum fog_mode,
-		      GLboolean saturate)
+_mesa_append_fog_code(struct gl_context *ctx, struct gl_program *fprog,
+                      GLenum fog_mode, GLboolean saturate)
 {
    static const gl_state_index fogPStateOpt[STATE_LENGTH]
       = { STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED, 0, 0, 0 };
    static const gl_state_index fogColorState[STATE_LENGTH]
       = { STATE_FOG_COLOR, 0, 0, 0, 0};
    struct prog_instruction *newInst, *inst;
-   const GLuint origLen = fprog->Base.NumInstructions;
+   const GLuint origLen = fprog->NumInstructions;
    const GLuint newLen = origLen + 5;
    GLuint i;
    GLint fogPRefOpt, fogColorRef; /* state references */
@@ -265,7 +264,7 @@ _mesa_append_fog_code(struct gl_context *ctx,
       return;
    }
 
-   if (!(fprog->Base.OutputsWritten & (1 << FRAG_RESULT_COLOR))) {
+   if (!(fprog->OutputsWritten & (1 << FRAG_RESULT_COLOR))) {
       /* program doesn't output color, so nothing to do */
       return;
    }
@@ -279,23 +278,23 @@ _mesa_append_fog_code(struct gl_context *ctx,
    }
 
    /* Copy orig instructions into new instruction buffer */
-   _mesa_copy_instructions(newInst, fprog->Base.Instructions, origLen);
+   _mesa_copy_instructions(newInst, fprog->Instructions, origLen);
 
    /* PARAM fogParamsRefOpt = internal optimized fog params; */
    fogPRefOpt
-      = _mesa_add_state_reference(fprog->Base.Parameters, fogPStateOpt);
+      = _mesa_add_state_reference(fprog->Parameters, fogPStateOpt);
    /* PARAM fogColorRef = state.fog.color; */
    fogColorRef
-      = _mesa_add_state_reference(fprog->Base.Parameters, fogColorState);
+      = _mesa_add_state_reference(fprog->Parameters, fogColorState);
 
    /* TEMP colorTemp; */
-   colorTemp = fprog->Base.NumTemporaries++;
+   colorTemp = fprog->NumTemporaries++;
    /* TEMP fogFactorTemp; */
-   fogFactorTemp = fprog->Base.NumTemporaries++;
+   fogFactorTemp = fprog->NumTemporaries++;
 
    /* Scan program to find where result.color is written */
    inst = newInst;
-   for (i = 0; i < fprog->Base.NumInstructions; i++) {
+   for (i = 0; i < fprog->NumInstructions; i++) {
       if (inst->Opcode == OPCODE_END)
          break;
       if (inst->DstReg.File == PROGRAM_OUTPUT &&
@@ -404,13 +403,13 @@ _mesa_append_fog_code(struct gl_context *ctx,
    inst++;
 
    /* free old instructions */
-   _mesa_free_instructions(fprog->Base.Instructions, origLen);
+   _mesa_free_instructions(fprog->Instructions, origLen);
 
    /* install new instructions */
-   fprog->Base.Instructions = newInst;
-   fprog->Base.NumInstructions = inst - newInst;
-   fprog->Base.InputsRead |= VARYING_BIT_FOGC;
-   assert(fprog->Base.OutputsWritten & (1 << FRAG_RESULT_COLOR));
+   fprog->Instructions = newInst;
+   fprog->NumInstructions = inst - newInst;
+   fprog->InputsRead |= VARYING_BIT_FOGC;
+   assert(fprog->OutputsWritten & (1 << FRAG_RESULT_COLOR));
 }
 
 
diff --git a/src/mesa/program/programopt.h b/src/mesa/program/programopt.h
index 2a76da4..5d70e57 100644
--- a/src/mesa/program/programopt.h
+++ b/src/mesa/program/programopt.h
@@ -38,9 +38,8 @@ extern void
 _mesa_insert_mvp_code(struct gl_context *ctx, struct gl_program *vprog);
 
 extern void
-_mesa_append_fog_code(struct gl_context *ctx,
-		      struct gl_fragment_program *fprog, GLenum fog_mode,
-		      GLboolean saturate);
+_mesa_append_fog_code(struct gl_context *ctx, struct gl_program *fprog,
+                      GLenum fog_mode, GLboolean saturate);
 
 extern void
 _mesa_count_texture_indirections(struct gl_program *prog);
diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c
index a86cffc..6f06d64 100644
--- a/src/mesa/state_tracker/st_atom.c
+++ b/src/mesa/state_tracker/st_atom.c
@@ -73,7 +73,7 @@ static void check_program_state( struct st_context *st )
    struct gl_program *new_tcp = ctx->TessCtrlProgram._Current;
    struct gl_program *new_tep = ctx->TessEvalProgram._Current;
    struct gl_program *new_gp = ctx->GeometryProgram._Current;
-   struct gl_fragment_program *new_fp = ctx->FragmentProgram._Current;
+   struct gl_program *new_fp = ctx->FragmentProgram._Current;
    uint64_t dirty = 0;
 
    /* Flag states used by both new and old shaders to unbind shader resources
diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c
index 31d1ef4..3b5031d 100644
--- a/src/mesa/state_tracker/st_atom_constbuf.c
+++ b/src/mesa/state_tracker/st_atom_constbuf.c
@@ -160,7 +160,7 @@ const struct st_tracked_state st_update_vs_constants = {
 static void update_fs_constants(struct st_context *st )
 {
    struct st_fragment_program *fp = st->fp;
-   struct gl_program_parameter_list *params = fp->Base.Base.Parameters;
+   struct gl_program_parameter_list *params = fp->Base.Parameters;
 
    st_upload_constants( st, params, MESA_SHADER_FRAGMENT );
 }
diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c
index e365a45..7f58c8b 100644
--- a/src/mesa/state_tracker/st_atom_rasterizer.c
+++ b/src/mesa/state_tracker/st_atom_rasterizer.c
@@ -63,7 +63,7 @@ static void update_raster_state( struct st_context *st )
    struct gl_context *ctx = st->ctx;
    struct pipe_rasterizer_state *raster = &st->state.rasterizer;
    const struct gl_program *vertProg = ctx->VertexProgram._Current;
-   const struct gl_fragment_program *fragProg = ctx->FragmentProgram._Current;
+   const struct gl_program *fragProg = ctx->FragmentProgram._Current;
 
    memset(raster, 0, sizeof(*raster));
 
@@ -183,7 +183,7 @@ static void update_raster_state( struct st_context *st )
       raster->sprite_coord_enable = ctx->Point.CoordReplace &
          ((1u << MAX_TEXTURE_COORD_UNITS) - 1);
       if (!st->needs_texcoord_semantic &&
-          fragProg->Base.InputsRead & VARYING_BIT_PNTC) {
+          fragProg->InputsRead & VARYING_BIT_PNTC) {
          raster->sprite_coord_enable |=
             1 << st_get_generic_varying_index(st, VARYING_SLOT_PNTC);
       }
diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c
index a7174f8..4568630 100644
--- a/src/mesa/state_tracker/st_atom_sampler.c
+++ b/src/mesa/state_tracker/st_atom_sampler.c
@@ -321,7 +321,7 @@ update_samplers(struct st_context *st)
 
    update_shader_samplers(st,
                           PIPE_SHADER_FRAGMENT,
-                          &ctx->FragmentProgram._Current->Base,
+                          ctx->FragmentProgram._Current,
                           ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits,
                           st->state.samplers[PIPE_SHADER_FRAGMENT],
                           &st->state.num_samplers[PIPE_SHADER_FRAGMENT]);
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index 1c3be08..b77000e 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -114,7 +114,7 @@ update_fp( struct st_context *st )
 
    assert(st->ctx->FragmentProgram._Current);
    stfp = st_fragment_program(st->ctx->FragmentProgram._Current);
-   assert(stfp->Base.Base.Target == GL_FRAGMENT_PROGRAM_ARB);
+   assert(stfp->Base.Target == GL_FRAGMENT_PROGRAM_ARB);
 
    memset(&key, 0, sizeof(key));
    key.st = st->has_shareable_shaders ? NULL : st;
@@ -143,7 +143,7 @@ update_fp( struct st_context *st )
       }
    }
 
-   key.external = st_get_external_sampler_key(st, &stfp->Base.Base);
+   key.external = st_get_external_sampler_key(st, &stfp->Base);
 
    st->fp_variant = st_get_fp_variant(st, stfp, &key);
 
diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c
index ea263ab..a1b1b88 100644
--- a/src/mesa/state_tracker/st_atom_texture.c
+++ b/src/mesa/state_tracker/st_atom_texture.c
@@ -222,7 +222,7 @@ update_fragment_textures(struct st_context *st)
 
    update_textures(st,
                    MESA_SHADER_FRAGMENT,
-                   &ctx->FragmentProgram._Current->Base,
+                   ctx->FragmentProgram._Current,
                    ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits,
                    st->state.sampler_views[PIPE_SHADER_FRAGMENT],
                    &st->state.num_sampler_views[PIPE_SHADER_FRAGMENT]);
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index 1e4becd..457c416 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -212,8 +212,7 @@ setup_render_state(struct gl_context *ctx,
       GLfloat colorSave[4];
       COPY_4V(colorSave, ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
       COPY_4V(ctx->Current.Attrib[VERT_ATTRIB_COLOR0], color);
-      st_upload_constants(st, st->fp->Base.Base.Parameters,
-                          MESA_SHADER_FRAGMENT);
+      st_upload_constants(st, st->fp->Base.Parameters, MESA_SHADER_FRAGMENT);
       COPY_4V(ctx->Current.Attrib[VERT_ATTRIB_COLOR0], colorSave);
    }
 
diff --git a/src/mesa/state_tracker/st_cb_bitmap.h b/src/mesa/state_tracker/st_cb_bitmap.h
index 323158e..d1b102e 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.h
+++ b/src/mesa/state_tracker/st_cb_bitmap.h
@@ -35,7 +35,7 @@
 
 struct dd_function_table;
 struct st_context;
-struct gl_fragment_program;
+struct gl_program;
 struct st_fragment_program;
 
 extern void
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 7f92e02..bc4e533 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -1123,8 +1123,7 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
       /* compiling a new fragment shader variant added new state constants
        * into the constant buffer, we need to update them
        */
-      st_upload_constants(st, st->fp->Base.Base.Parameters,
-                          MESA_SHADER_FRAGMENT);
+      st_upload_constants(st, st->fp->Base.Parameters, MESA_SHADER_FRAGMENT);
    }
 
    /* Put glDrawPixels image into a texture */
@@ -1487,8 +1486,7 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
       /* compiling a new fragment shader variant added new state constants
        * into the constant buffer, we need to update them
        */
-      st_upload_constants(st, st->fp->Base.Base.Parameters,
-                          MESA_SHADER_FRAGMENT);
+      st_upload_constants(st, st->fp->Base.Parameters, MESA_SHADER_FRAGMENT);
    }
    else {
       assert(type == GL_DEPTH);
diff --git a/src/mesa/state_tracker/st_cb_drawtex.c b/src/mesa/state_tracker/st_cb_drawtex.c
index 3321e15..2991a09 100644
--- a/src/mesa/state_tracker/st_cb_drawtex.c
+++ b/src/mesa/state_tracker/st_cb_drawtex.c
@@ -123,7 +123,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
    st_validate_state(st, ST_PIPELINE_RENDER);
 
    /* determine if we need vertex color */
-   if (ctx->FragmentProgram._Current->Base.InputsRead & VARYING_BIT_COL0)
+   if (ctx->FragmentProgram._Current->InputsRead & VARYING_BIT_COL0)
       emitColor = GL_TRUE;
    else
       emitColor = GL_FALSE;
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index d0478ca..48720a3 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -63,7 +63,7 @@ st_new_program(struct gl_context *ctx, GLenum target, GLuint id)
    }
    case GL_FRAGMENT_PROGRAM_ARB: {
       struct st_fragment_program *prog = ST_CALLOC_STRUCT(st_fragment_program);
-      return _mesa_init_gl_program(&prog->Base.Base, target, id);
+      return _mesa_init_gl_program(&prog->Base, target, id);
    }
    case GL_GEOMETRY_PROGRAM_NV: {
       struct st_geometry_program *prog = ST_CALLOC_STRUCT(st_geometry_program);
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 174503f..0eae971 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -262,7 +262,7 @@ void st_invalidate_state(struct gl_context * ctx, GLbitfield new_state)
                     ST_NEW_SAMPLERS |
                     ST_NEW_IMAGE_UNITS);
       if (ctx->FragmentProgram._Current &&
-          ctx->FragmentProgram._Current->Base.ExternalSamplersUsed) {
+          ctx->FragmentProgram._Current->ExternalSamplersUsed) {
          st->dirty |= ST_NEW_FS_STATE;
       }
    }
diff --git a/src/mesa/state_tracker/st_debug.c b/src/mesa/state_tracker/st_debug.c
index 1e5bbba..d6cb5cd 100644
--- a/src/mesa/state_tracker/st_debug.c
+++ b/src/mesa/state_tracker/st_debug.c
@@ -102,8 +102,8 @@ st_print_current(void)
       _mesa_print_parameter_list(st->vp->Base.Parameters);
 
    tgsi_dump(st->fp->tgsi.tokens, 0);
-   if (st->fp->Base.Base.Parameters)
-      _mesa_print_parameter_list(st->fp->Base.Base.Parameters);
+   if (st->fp->Base.Parameters)
+      _mesa_print_parameter_list(st->fp->Base.Parameters);
 }
 
 
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index b563bec..2bf0c3e 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -1301,10 +1301,8 @@ void
 glsl_to_tgsi_visitor::visit(ir_variable *ir)
 {
    if (strcmp(ir->name, "gl_FragCoord") == 0) {
-      struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog;
-
-      fp->OriginUpperLeft = ir->data.origin_upper_left;
-      fp->PixelCenterInteger = ir->data.pixel_center_integer;
+      this->prog->OriginUpperLeft = ir->data.origin_upper_left;
+      this->prog->PixelCenterInteger = ir->data.pixel_center_integer;
    }
 
    if (ir->data.mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) {
@@ -5977,8 +5975,6 @@ emit_wpos(struct st_context *st,
           struct ureg_program *ureg,
           int wpos_transform_const)
 {
-   const struct gl_fragment_program *fp =
-      (const struct gl_fragment_program *) program;
    struct pipe_screen *pscreen = st->pipe->screen;
    GLfloat adjX = 0.0f;
    GLfloat adjY[2] = { 0.0f, 0.0f };
@@ -6011,7 +6007,7 @@ emit_wpos(struct st_context *st,
     * u,i -> l,h: (99.0 + 0.5) * -1 + 100 = 0.5
     * u,h -> l,i: (99.5 + 0.5) * -1 + 100 = 0
     */
-   if (fp->OriginUpperLeft) {
+   if (program->OriginUpperLeft) {
       /* Fragment shader wants origin in upper-left */
       if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) {
          /* the driver supports upper-left origin */
@@ -6038,7 +6034,7 @@ emit_wpos(struct st_context *st,
          assert(0);
    }
 
-   if (fp->PixelCenterInteger) {
+   if (program->PixelCenterInteger) {
       /* Fragment shader wants pixel center integer */
       if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) {
          /* the driver supports pixel center integer */
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index b989257..33db0ae 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -818,8 +818,6 @@ emit_wpos(struct st_context *st,
           const struct gl_program *program,
           struct ureg_program *ureg)
 {
-   const struct gl_fragment_program *fp =
-      (const struct gl_fragment_program *) program;
    struct pipe_screen *pscreen = st->pipe->screen;
    GLfloat adjX = 0.0f;
    GLfloat adjY[2] = { 0.0f, 0.0f };
@@ -852,7 +850,7 @@ emit_wpos(struct st_context *st,
     * u,i -> l,h: (99.0 + 0.5) * -1 + 100 = 0.5
     * u,h -> l,i: (99.5 + 0.5) * -1 + 100 = 0
     */
-   if (fp->OriginUpperLeft) {
+   if (program->OriginUpperLeft) {
       /* Fragment shader wants origin in upper-left */
       if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) {
          /* the driver supports upper-left origin */
@@ -879,7 +877,7 @@ emit_wpos(struct st_context *st,
          assert(0);
    }
    
-   if (fp->PixelCenterInteger) {
+   if (program->PixelCenterInteger) {
       /* Fragment shader wants pixel center integer */
       if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) {
          /* the driver supports pixel center integer */
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index b6275e5..ebe05ba 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -586,9 +586,9 @@ st_translate_fragment_program(struct st_context *st,
 
    /* Non-GLSL programs: */
    if (!stfp->glsl_to_tgsi && !stfp->shader_program) {
-      _mesa_remove_output_reads(&stfp->Base.Base, PROGRAM_OUTPUT);
+      _mesa_remove_output_reads(&stfp->Base, PROGRAM_OUTPUT);
       if (st->ctx->Const.GLSLFragCoordIsSysVal)
-         _mesa_program_fragment_position_to_sysval(&stfp->Base.Base);
+         _mesa_program_fragment_position_to_sysval(&stfp->Base);
 
       /* This determines which states will be updated when the assembly
        * shader is bound.
@@ -605,7 +605,7 @@ st_translate_fragment_program(struct st_context *st,
                                   ST_NEW_RENDER_SAMPLERS;
       } else {
          /* ARB_fp */
-         if (stfp->Base.Base.SamplersUsed)
+         if (stfp->Base.SamplersUsed)
             stfp->affected_states |= ST_NEW_FS_SAMPLER_VIEWS |
                                      ST_NEW_RENDER_SAMPLERS;
       }
@@ -614,7 +614,7 @@ st_translate_fragment_program(struct st_context *st,
    /*
     * Convert Mesa program inputs to TGSI input register semantics.
     */
-   inputsRead = stfp->Base.Base.InputsRead;
+   inputsRead = stfp->Base.InputsRead;
    for (attr = 0; attr < VARYING_SLOT_MAX; attr++) {
       if ((inputsRead & BITFIELD64_BIT(attr)) != 0) {
          const GLuint slot = fs_num_inputs++;
@@ -753,7 +753,7 @@ st_translate_fragment_program(struct st_context *st,
     * Semantics and mapping for outputs
     */
    {
-      GLbitfield64 outputsWritten = stfp->Base.Base.OutputsWritten;
+      GLbitfield64 outputsWritten = stfp->Base.OutputsWritten;
 
       /* if z is written, emit that first */
       if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
@@ -783,7 +783,7 @@ st_translate_fragment_program(struct st_context *st,
       /* handle remaining outputs (color) */
       for (attr = 0; attr < ARRAY_SIZE(outputMapping); attr++) {
          const GLbitfield64 written = attr < FRAG_RESULT_MAX ? outputsWritten :
-            stfp->Base.Base.SecondaryOutputsWritten;
+            stfp->Base.SecondaryOutputsWritten;
          const unsigned loc = attr % FRAG_RESULT_MAX;
 
          if (written & BITFIELD64_BIT(loc)) {
@@ -822,8 +822,7 @@ st_translate_fragment_program(struct st_context *st,
    }
 
    if (stfp->shader_program) {
-      nir_shader *nir = st_glsl_to_nir(st, &stfp->Base.Base,
-                                       stfp->shader_program,
+      nir_shader *nir = st_glsl_to_nir(st, &stfp->Base, stfp->shader_program,
                                        MESA_SHADER_FRAGMENT);
 
       stfp->tgsi.type = PIPE_SHADER_IR_NIR;
@@ -837,15 +836,15 @@ st_translate_fragment_program(struct st_context *st,
       return false;
 
    if (ST_DEBUG & DEBUG_MESA) {
-      _mesa_print_program(&stfp->Base.Base);
-      _mesa_print_program_parameters(st->ctx, &stfp->Base.Base);
+      _mesa_print_program(&stfp->Base);
+      _mesa_print_program_parameters(st->ctx, &stfp->Base);
       debug_printf("\n");
    }
    if (write_all == GL_TRUE)
       ureg_property(ureg, TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS, 1);
 
-   if (stfp->Base.FragDepthLayout != FRAG_DEPTH_LAYOUT_NONE) {
-      switch (stfp->Base.FragDepthLayout) {
+   if (stfp->Base.info.fs.depth_layout != FRAG_DEPTH_LAYOUT_NONE) {
+      switch (stfp->Base.info.fs.depth_layout) {
       case FRAG_DEPTH_LAYOUT_ANY:
          ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT,
                        TGSI_FS_DEPTH_LAYOUT_ANY);
@@ -872,7 +871,7 @@ st_translate_fragment_program(struct st_context *st,
                            PIPE_SHADER_FRAGMENT,
                            ureg,
                            stfp->glsl_to_tgsi,
-                           &stfp->Base.Base,
+                           &stfp->Base,
                            /* inputs */
                            fs_num_inputs,
                            inputMapping,
@@ -892,7 +891,7 @@ st_translate_fragment_program(struct st_context *st,
    } else if (stfp->ati_fs)
       st_translate_atifs_program(ureg,
                                  stfp->ati_fs,
-                                 &stfp->Base.Base,
+                                 &stfp->Base,
                                  /* inputs */
                                  fs_num_inputs,
                                  inputMapping,
@@ -908,7 +907,7 @@ st_translate_fragment_program(struct st_context *st,
       st_translate_mesa_program(st->ctx,
                                 PIPE_SHADER_FRAGMENT,
                                 ureg,
-                                &stfp->Base.Base,
+                                &stfp->Base,
                                 /* inputs */
                                 fs_num_inputs,
                                 inputMapping,
@@ -934,7 +933,7 @@ st_create_fp_variant(struct st_context *st,
    struct pipe_context *pipe = st->pipe;
    struct st_fp_variant *variant = CALLOC_STRUCT(st_fp_variant);
    struct pipe_shader_state tgsi = {0};
-   struct gl_program_parameter_list *params = stfp->Base.Base.Parameters;
+   struct gl_program_parameter_list *params = stfp->Base.Parameters;
    static const gl_state_index texcoord_state[STATE_LENGTH] =
       { STATE_INTERNAL, STATE_CURRENT_ATTRIB, VERT_ATTRIB_TEX0 };
    static const gl_state_index scale_state[STATE_LENGTH] =
@@ -964,7 +963,7 @@ st_create_fp_variant(struct st_context *st,
       if (key->bitmap) {
          nir_lower_bitmap_options options = {0};
 
-         variant->bitmap_sampler = ffs(~stfp->Base.Base.SamplersUsed) - 1;
+         variant->bitmap_sampler = ffs(~stfp->Base.SamplersUsed) - 1;
          options.sampler = variant->bitmap_sampler;
          options.swizzle_xxxx = (st->bitmap.tex_format == PIPE_FORMAT_L8_UNORM);
 
@@ -974,7 +973,7 @@ st_create_fp_variant(struct st_context *st,
       /* glDrawPixels (color only) */
       if (key->drawpixels) {
          nir_lower_drawpixels_options options = {{0}};
-         unsigned samplers_used = stfp->Base.Base.SamplersUsed;
+         unsigned samplers_used = stfp->Base.SamplersUsed;
 
          /* Find the first unused slot. */
          variant->drawpix_sampler = ffs(~samplers_used) - 1;
@@ -1011,12 +1010,12 @@ st_create_fp_variant(struct st_context *st,
          NIR_PASS_V(tgsi.ir.nir, nir_lower_tex, &options);
       }
 
-      st_finalize_nir(st, &stfp->Base.Base, tgsi.ir.nir);
+      st_finalize_nir(st, &stfp->Base, tgsi.ir.nir);
 
       if (unlikely(key->external.lower_nv12 || key->external.lower_iyuv)) {
          /* This pass needs to happen *after* nir_lower_sampler */
          NIR_PASS_V(tgsi.ir.nir, st_nir_lower_tex_src_plane,
-                    ~stfp->Base.Base.SamplersUsed,
+                    ~stfp->Base.SamplersUsed,
                     key->external.lower_nv12,
                     key->external.lower_iyuv);
       }
@@ -1062,7 +1061,7 @@ st_create_fp_variant(struct st_context *st,
    if (key->bitmap) {
       const struct tgsi_token *tokens;
 
-      variant->bitmap_sampler = ffs(~stfp->Base.Base.SamplersUsed) - 1;
+      variant->bitmap_sampler = ffs(~stfp->Base.SamplersUsed) - 1;
 
       tokens = st_get_bitmap_shader(tgsi.tokens,
                                     st->internal_target,
@@ -1085,10 +1084,10 @@ st_create_fp_variant(struct st_context *st,
       unsigned scale_const = 0, bias_const = 0, texcoord_const = 0;
 
       /* Find the first unused slot. */
-      variant->drawpix_sampler = ffs(~stfp->Base.Base.SamplersUsed) - 1;
+      variant->drawpix_sampler = ffs(~stfp->Base.SamplersUsed) - 1;
 
       if (key->pixelMaps) {
-         unsigned samplers_used = stfp->Base.Base.SamplersUsed |
+         unsigned samplers_used = stfp->Base.SamplersUsed |
                                   (1 << variant->drawpix_sampler);
 
          variant->pixelmap_sampler = ffs(~samplers_used) - 1;
@@ -1124,7 +1123,7 @@ st_create_fp_variant(struct st_context *st,
       assert(!(key->bitmap || key->drawpixels));
 
       tokens = st_tgsi_lower_yuv(tgsi.tokens,
-                                 ~stfp->Base.Base.SamplersUsed,
+                                 ~stfp->Base.SamplersUsed,
                                  key->external.lower_nv12,
                                  key->external.lower_iyuv);
       if (tokens) {
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
index deb7009..eb36ac3 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -136,11 +136,11 @@ struct st_fp_variant
 
 
 /**
- * Derived from Mesa gl_fragment_program:
+ * Derived from Mesa gl_program:
  */
 struct st_fragment_program
 {
-   struct gl_fragment_program Base;
+   struct gl_program Base;
    struct pipe_shader_state tgsi;
    struct glsl_to_tgsi_visitor* glsl_to_tgsi;
    struct ati_fragment_shader *ati_fs;
@@ -197,7 +197,7 @@ struct st_vp_variant
 
 
 /**
- * Derived from Mesa gl_fragment_program:
+ * Derived from Mesa gl_program:
  */
 struct st_vertex_program
 {
@@ -302,7 +302,7 @@ struct st_compute_program
 
 
 static inline struct st_fragment_program *
-st_fragment_program( struct gl_fragment_program *fp )
+st_fragment_program( struct gl_program *fp )
 {
    return (struct st_fragment_program *)fp;
 }
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c
index a63179c..3eb931f 100644
--- a/src/mesa/swrast/s_context.c
+++ b/src/mesa/swrast/s_context.c
@@ -220,13 +220,12 @@ _swrast_update_deferred_texture(struct gl_context *ctx)
    }
    else {
       GLboolean use_fprog = _swrast_use_fragment_program(ctx);
-      const struct gl_fragment_program *fprog
-         = ctx->FragmentProgram._Current;
-      if (use_fprog && (fprog->Base.OutputsWritten & (1 << FRAG_RESULT_DEPTH))) {
+      const struct gl_program *fprog = ctx->FragmentProgram._Current;
+      if (use_fprog && (fprog->OutputsWritten & (1 << FRAG_RESULT_DEPTH))) {
          /* Z comes from fragment program/shader */
          swrast->_DeferredTexture = GL_FALSE;
       }
-      else if (use_fprog && fprog->UsesKill) {
+      else if (use_fprog && fprog->info.fs.uses_discard) {
          swrast->_DeferredTexture = GL_FALSE;
       }
       else if (ctx->Query.CurrentOcclusionObject) {
@@ -247,9 +246,9 @@ static void
 _swrast_update_fog_state( struct gl_context *ctx )
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
+   const struct gl_program *fp = ctx->FragmentProgram._Current;
 
-   assert(fp == NULL || fp->Base.Target == GL_FRAGMENT_PROGRAM_ARB);
+   assert(fp == NULL || fp->Target == GL_FRAGMENT_PROGRAM_ARB);
    (void) fp; /* silence unused var warning */
 
    /* determine if fog is needed, and if so, which fog mode */
@@ -269,7 +268,7 @@ _swrast_update_fragment_program(struct gl_context *ctx, GLbitfield newState)
       return;
 
    _mesa_load_state_parameters(ctx,
-                               ctx->FragmentProgram._Current->Base.Parameters);
+                               ctx->FragmentProgram._Current->Parameters);
 }
 
 
@@ -500,7 +499,7 @@ _swrast_update_active_attribs(struct gl_context *ctx)
     */
    if (_swrast_use_fragment_program(ctx)) {
       /* fragment program/shader */
-      attribsMask = ctx->FragmentProgram._Current->Base.InputsRead;
+      attribsMask = ctx->FragmentProgram._Current->InputsRead;
       attribsMask &= ~VARYING_BIT_POS; /* WPOS is always handled specially */
    }
    else if (ctx->ATIFragmentShader._Enabled) {
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
index 022fb17..3530b50 100644
--- a/src/mesa/swrast/s_fragprog.c
+++ b/src/mesa/swrast/s_fragprog.c
@@ -41,9 +41,9 @@
 GLboolean
 _swrast_use_fragment_program(struct gl_context *ctx)
 {
-   struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
+   struct gl_program *fp = ctx->FragmentProgram._Current;
    return fp && !(fp == ctx->FragmentProgram._TexEnvProgram
-                  && fp->Base.NumInstructions == 0);
+                  && fp->NumInstructions == 0);
 }
 
 /**
@@ -159,8 +159,7 @@ fetch_texel_deriv( struct gl_context *ctx, const GLfloat texcoord[4],
  */
 static void
 init_machine(struct gl_context *ctx, struct gl_program_machine *machine,
-             const struct gl_fragment_program *program,
-             const SWspan *span, GLuint col)
+             const struct gl_program *program, const SWspan *span, GLuint col)
 {
    GLfloat *wpos = span->array->attribs[VARYING_SLOT_POS][col];
 
@@ -179,7 +178,7 @@ init_machine(struct gl_context *ctx, struct gl_program_machine *machine,
    machine->DerivY = (GLfloat (*)[4]) span->attrStepY;
    machine->NumDeriv = VARYING_SLOT_MAX;
 
-   machine->Samplers = program->Base.SamplerUnits;
+   machine->Samplers = program->SamplerUnits;
 
    /* if running a GLSL program (not ARB_fragment_program) */
    if (ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]) {
@@ -204,8 +203,8 @@ static void
 run_program(struct gl_context *ctx, SWspan *span, GLuint start, GLuint end)
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
-   const struct gl_fragment_program *program = ctx->FragmentProgram._Current;
-   const GLbitfield64 outputsWritten = program->Base.OutputsWritten;
+   const struct gl_program *program = ctx->FragmentProgram._Current;
+   const GLbitfield64 outputsWritten = program->OutputsWritten;
    struct gl_program_machine *machine = &swrast->FragProgMachine;
    GLuint i;
 
@@ -213,7 +212,7 @@ run_program(struct gl_context *ctx, SWspan *span, GLuint start, GLuint end)
       if (span->array->mask[i]) {
          init_machine(ctx, machine, program, span, i);
 
-         if (_mesa_execute_program(ctx, &program->Base, machine)) {
+         if (_mesa_execute_program(ctx, program, machine)) {
 
             /* Store result color */
 	    if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) {
@@ -263,21 +262,21 @@ run_program(struct gl_context *ctx, SWspan *span, GLuint start, GLuint end)
 void
 _swrast_exec_fragment_program( struct gl_context *ctx, SWspan *span )
 {
-   const struct gl_fragment_program *program = ctx->FragmentProgram._Current;
+   const struct gl_program *program = ctx->FragmentProgram._Current;
 
    /* incoming colors should be floats */
-   if (program->Base.InputsRead & VARYING_BIT_COL0) {
+   if (program->InputsRead & VARYING_BIT_COL0) {
       assert(span->array->ChanType == GL_FLOAT);
    }
 
    run_program(ctx, span, 0, span->end);
 
-   if (program->Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) {
+   if (program->OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) {
       span->interpMask &= ~SPAN_RGBA;
       span->arrayMask |= SPAN_RGBA;
    }
 
-   if (program->Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
+   if (program->OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
       span->interpMask &= ~SPAN_Z;
       span->arrayMask |= SPAN_Z;
    }
diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c
index cd939ba..949c230 100644
--- a/src/mesa/swrast/s_span.c
+++ b/src/mesa/swrast/s_span.c
@@ -1310,10 +1310,10 @@ _swrast_write_rgba_span( struct gl_context *ctx, SWspan *span)
     */
    {
       const GLuint numBuffers = fb->_NumColorDrawBuffers;
-      const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
+      const struct gl_program *fp = ctx->FragmentProgram._Current;
       const GLboolean multiFragOutputs = 
          _swrast_use_fragment_program(ctx)
-         && fp->Base.OutputsWritten >= (1 << FRAG_RESULT_DATA0);
+         && fp->OutputsWritten >= (1 << FRAG_RESULT_DATA0);
       /* Save srcColorType because convert_color_type() can change it */
       const GLenum srcColorType = span->array->ChanType;
       GLuint buf;
diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c
index 3810043..9b7982e 100644
--- a/src/mesa/tnl/t_context.c
+++ b/src/mesa/tnl/t_context.c
@@ -132,7 +132,7 @@ _tnl_InvalidateState( struct gl_context *ctx, GLuint new_state )
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    const struct gl_program *vp = ctx->VertexProgram._Current;
-   const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
+   const struct gl_program *fp = ctx->FragmentProgram._Current;
    GLuint i;
 
    if (new_state & (_NEW_HINT | _NEW_PROGRAM)) {
@@ -148,7 +148,7 @@ _tnl_InvalidateState( struct gl_context *ctx, GLuint new_state )
     */
    tnl->render_inputs_bitset = BITFIELD64_BIT(_TNL_ATTRIB_POS);
 
-   if (!fp || (fp->Base.InputsRead & VARYING_BIT_COL0)) {
+   if (!fp || (fp->InputsRead & VARYING_BIT_COL0)) {
      tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_COLOR0);
    }
 
@@ -157,13 +157,13 @@ _tnl_InvalidateState( struct gl_context *ctx, GLuint new_state )
 
    for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
      if (ctx->Texture._EnabledCoordUnits & (1 << i) ||
-	 (fp && fp->Base.InputsRead & VARYING_BIT_TEX(i))) {
+	 (fp && fp->InputsRead & VARYING_BIT_TEX(i))) {
        tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_TEX(i));
      }
    }
 
    if (ctx->Fog.Enabled
-       || (fp != NULL && (fp->Base.InputsRead & VARYING_BIT_FOGC) != 0)) {
+       || (fp != NULL && (fp->InputsRead & VARYING_BIT_FOGC) != 0)) {
       /* Either fixed-function fog or a fragment program needs fog coord.
        */
       tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_FOG);
-- 
2.7.4



More information about the mesa-dev mailing list