[Mesa-dev] [PATCH 5/7] glsl/mesa: split gl_shader in two

Timothy Arceri timothy.arceri at collabora.com
Wed Jun 29 12:26:18 UTC 2016


On Wed, 2016-06-29 at 13:57 +0200, Iago Toral wrote:
> On Tue, 2016-06-28 at 11:52 +1000, Timothy Arceri wrote:
> > There are two distinctly different uses of this struct. The first
> > is to store GL shader objects. The second is to store information
> > about a shader stage thats been linked.
> > 
> > The two uses actually share few fields and there is clearly
> > confusion
> > about their use. For example the linked shaders map one to one with
> > a program so can simply be destroyed along with the program.
> > However
> > previously we were calling reference counting on the linked
> > shaders.
> > 
> > We were also creating linked shaders with a name even though it
> > is always 0 and called the driver version of the _mesa_new_shader()
> > function unnecessarily for GL shader objects.
> > ---
> >  src/compiler/glsl/glsl_to_nir.cpp                  |   2 +-
> >  src/compiler/glsl/ir_optimization.h                |  23 ++--
> >  src/compiler/glsl/link_atomics.cpp                 |   2 +-
> >  src/compiler/glsl/link_functions.cpp               |   8 +-
> >  src/compiler/glsl/link_interface_blocks.cpp        |  10 +-
> >  src/compiler/glsl/link_uniform_blocks.cpp          |   2 +-
> >  src/compiler/glsl/link_uniform_initializers.cpp    |   6 +-
> >  src/compiler/glsl/link_uniforms.cpp                |   8 +-
> >  src/compiler/glsl/link_varyings.cpp                |  17 ++-
> >  src/compiler/glsl/link_varyings.h                  |  17 ++-
> >  src/compiler/glsl/linker.cpp                       | 106 +++++++
> > --------
> >  src/compiler/glsl/linker.h                         |  10 +-
> >  src/compiler/glsl/lower_distance.cpp               |   3 +-
> >  src/compiler/glsl/lower_named_interface_blocks.cpp |   2 +-
> >  src/compiler/glsl/lower_packed_varyings.cpp        |   6 +-
> >  src/compiler/glsl/lower_shared_reference.cpp       |   6 +-
> >  src/compiler/glsl/lower_tess_level.cpp             |   2 +-
> >  src/compiler/glsl/lower_ubo_reference.cpp          |   6 +-
> >  src/compiler/glsl/lower_vector_derefs.cpp          |   2 +-
> >  src/compiler/glsl/lower_vertex_id.cpp              |   2 +-
> >  src/compiler/glsl/opt_dead_builtin_varyings.cpp    |  11 +-
> >  src/compiler/glsl/standalone.cpp                   |   4 +-
> >  src/compiler/glsl/standalone_scaffolding.cpp       |  20 +++
> >  src/compiler/glsl/standalone_scaffolding.h         |   7 +
> >  src/compiler/glsl/test_optpass.cpp                 |   2 +-
> >  src/mesa/drivers/common/meta.c                     |   2 +-
> >  src/mesa/drivers/dri/i965/brw_context.c            |   5 +-
> >  src/mesa/drivers/dri/i965/brw_context.h            |   8 +-
> >  src/mesa/drivers/dri/i965/brw_gs.c                 |   5 +-
> >  src/mesa/drivers/dri/i965/brw_link.cpp             |  24 ++--
> >  src/mesa/drivers/dri/i965/brw_program.c            |   2 +-
> >  src/mesa/drivers/dri/i965/brw_program.h            |   2 +-
> >  src/mesa/drivers/dri/i965/brw_shader.cpp           |   4 +-
> >  src/mesa/drivers/dri/i965/brw_shader.h             |   3 +-
> >  src/mesa/drivers/dri/i965/brw_tcs.c                |   2 +-
> >  src/mesa/drivers/dri/i965/brw_tes.c                |   3 +-
> >  src/mesa/drivers/dri/i965/brw_wm_surface_state.c   |   6 +-
> >  src/mesa/main/api_validate.c                       |   6 +-
> >  src/mesa/main/dd.h                                 |   3 +-
> >  src/mesa/main/ff_fragment_shader.cpp               |   2 +-
> >  src/mesa/main/mtypes.h                             | 143
> > ++++++++++++++++++---
> >  src/mesa/main/shader_query.cpp                     |   2 +-
> >  src/mesa/main/shaderapi.c                          |  19 +--
> >  src/mesa/main/shaderobj.c                          |  32 ++++-
> >  src/mesa/main/shaderobj.h                          |   7 +
> >  src/mesa/main/uniform_query.cpp                    |   4 +-
> >  src/mesa/main/uniforms.c                           |   2 +-
> >  src/mesa/program/ir_to_mesa.cpp                    |   4 +-
> >  src/mesa/program/ir_to_mesa.h                      |   2 +-
> >  src/mesa/program/prog_print.c                      |  14 +-
> >  src/mesa/program/prog_print.h                      |   2 +-
> >  src/mesa/state_tracker/st_atom_constbuf.c          |   2 +-
> >  src/mesa/state_tracker/st_atom_image.c             |   2 +-
> >  src/mesa/state_tracker/st_atom_storagebuf.c        |   2 +-
> >  src/mesa/state_tracker/st_glsl_to_nir.cpp          |   2 +-
> >  src/mesa/state_tracker/st_glsl_to_tgsi.cpp         |   6 +-
> >  src/mesa/state_tracker/st_nir.h                    |   2 +-
> >  src/mesa/state_tracker/st_program.c                |   7 -
> >  58 files changed, 388 insertions(+), 227 deletions(-)
> > 
> > diff --git a/src/compiler/glsl/glsl_to_nir.cpp
> > b/src/compiler/glsl/glsl_to_nir.cpp
> > index a22fd5b..0ad3be1 100644
> > --- a/src/compiler/glsl/glsl_to_nir.cpp
> > +++ b/src/compiler/glsl/glsl_to_nir.cpp
> > @@ -134,7 +134,7 @@ glsl_to_nir(const struct gl_shader_program
> > *shader_prog,
> >              gl_shader_stage stage,
> >              const nir_shader_compiler_options *options)
> >  {
> > -   struct gl_shader *sh = shader_prog->_LinkedShaders[stage];
> > +   struct gl_linked_shader *sh = shader_prog-
> > >_LinkedShaders[stage];
> >  
> >     nir_shader *shader = nir_shader_create(NULL, stage, options);
> >  
> > diff --git a/src/compiler/glsl/ir_optimization.h
> > b/src/compiler/glsl/ir_optimization.h
> > index ba14e34..ba79076 100644
> > --- a/src/compiler/glsl/ir_optimization.h
> > +++ b/src/compiler/glsl/ir_optimization.h
> > @@ -86,7 +86,8 @@ bool do_copy_propagation(exec_list
> > *instructions);
> >  bool do_copy_propagation_elements(exec_list *instructions);
> >  bool do_constant_propagation(exec_list *instructions);
> >  void do_dead_builtin_varyings(struct gl_context *ctx,
> > -                              gl_shader *producer, gl_shader
> > *consumer,
> > +                              gl_linked_shader *producer,
> > +                              gl_linked_shader *consumer,
> >                                unsigned num_tfeedback_decls,
> >                                class tfeedback_decl
> > *tfeedback_decls);
> >  bool do_dead_code(exec_list *instructions, bool
> > uniform_locations_assigned);
> > @@ -119,26 +120,30 @@ bool
> > lower_variable_index_to_cond_assign(gl_shader_stage stage,
> >      bool lower_temp, bool lower_uniform);
> >  bool lower_quadop_vector(exec_list *instructions, bool
> > dont_lower_swz);
> >  bool lower_const_arrays_to_uniforms(exec_list *instructions);
> > -bool lower_clip_cull_distance(struct gl_shader_program *prog,
> > gl_shader *shader);
> > +bool lower_clip_cull_distance(struct gl_shader_program *prog,
> > +                              gl_linked_shader *shader);
> >  void lower_output_reads(unsigned stage, exec_list *instructions);
> >  bool lower_packing_builtins(exec_list *instructions, int op_mask);
> > -void lower_shared_reference(struct gl_shader *shader, unsigned
> > *shared_size);
> > -void lower_ubo_reference(struct gl_shader *shader, bool
> > clamp_block_indices);
> > +void lower_shared_reference(struct gl_linked_shader *shader,
> > +                            unsigned *shared_size);
> > +void lower_ubo_reference(struct gl_linked_shader *shader,
> > +                         bool clamp_block_indices);
> >  void lower_packed_varyings(void *mem_ctx,
> >                             unsigned locations_used,
> > ir_variable_mode mode,
> > -                           unsigned gs_input_vertices, gl_shader
> > *shader,
> > +                           unsigned gs_input_vertices,
> > +                           gl_linked_shader *shader,
> >                             bool disable_varying_packing, bool
> > xfb_enabled);
> >  bool lower_vector_insert(exec_list *instructions, bool
> > lower_nonconstant_index);
> > -bool lower_vector_derefs(gl_shader *shader);
> > -void lower_named_interface_blocks(void *mem_ctx, gl_shader
> > *shader);
> > +bool lower_vector_derefs(gl_linked_shader *shader);
> > +void lower_named_interface_blocks(void *mem_ctx, gl_linked_shader
> > *shader);
> >  bool optimize_redundant_jumps(exec_list *instructions);
> >  bool optimize_split_arrays(exec_list *instructions, bool linked);
> >  bool lower_offset_arrays(exec_list *instructions);
> >  void optimize_dead_builtin_variables(exec_list *instructions,
> >                                       enum ir_variable_mode other);
> > -bool lower_tess_level(gl_shader *shader);
> > +bool lower_tess_level(gl_linked_shader *shader);
> >  
> > -bool lower_vertex_id(gl_shader *shader);
> > +bool lower_vertex_id(gl_linked_shader *shader);
> >  
> >  bool lower_subroutine(exec_list *instructions, struct
> > _mesa_glsl_parse_state *state);
> >  void propagate_invariance(exec_list *instructions);
> > diff --git a/src/compiler/glsl/link_atomics.cpp
> > b/src/compiler/glsl/link_atomics.cpp
> > index 277d473..fa845e9 100644
> > --- a/src/compiler/glsl/link_atomics.cpp
> > +++ b/src/compiler/glsl/link_atomics.cpp
> > @@ -150,7 +150,7 @@ namespace {
> >        *num_buffers = 0;
> >  
> >        for (unsigned i = 0; i < MESA_SHADER_STAGES; ++i) {
> > -         struct gl_shader *sh = prog->_LinkedShaders[i];
> > +         struct gl_linked_shader *sh = prog->_LinkedShaders[i];
> >           if (sh == NULL)
> >              continue;
> >  
> > diff --git a/src/compiler/glsl/link_functions.cpp
> > b/src/compiler/glsl/link_functions.cpp
> > index c9dacc1..079f3b9 100644
> > --- a/src/compiler/glsl/link_functions.cpp
> > +++ b/src/compiler/glsl/link_functions.cpp
> > @@ -37,7 +37,7 @@ namespace {
> >  
> >  class call_link_visitor : public ir_hierarchical_visitor {
> >  public:
> > -   call_link_visitor(gl_shader_program *prog, gl_shader *linked,
> > +   call_link_visitor(gl_shader_program *prog, gl_linked_shader
> > *linked,
> >  		     gl_shader **shader_list, unsigned
> > num_shaders)
> >     {
> >        this->prog = prog;
> > @@ -297,7 +297,7 @@ private:
> >      * linked shader that are accessed by the function.  It is also
> > used to add
> >      * global variables from the shader where the function
> > originated.
> >      */
> > -   gl_shader *linked;
> > +   gl_linked_shader *linked;
> >  
> >     /**
> >      * Table of variables local to the function.
> > @@ -325,7 +325,7 @@ find_matching_signature(const char *name, const
> > exec_list *actual_parameters,
> >            * signature that we found isn't a built-in, keep
> > looking.  Also keep
> >            * looking if we expect a non-built-in but found a built-
> > in.
> >            */
> > -         if (use_builtin != sig->is_builtin())
> > +         if (use_builtin == sig->is_builtin())
> 
> Uh, this is what I mentioned in a previous patch, I guess you meant
> to
> put this hunk into that other patch instead.
> 

Hi, thanks for reviewing these :) Yes I thought I sent out an email in
reply to patch 4 right after sending the series saying I squashed the
fix into the wrong patch, maybe it didn't get through? Anyway I've
fixed it up locally. 

Nice catch by the way. 


> >              return sig;
> >        }
> >     }
> > @@ -335,7 +335,7 @@ find_matching_signature(const char *name, const
> > exec_list *actual_parameters,
> >  
> > 
> >  bool
> > -link_function_calls(gl_shader_program *prog, gl_shader *main,
> > +link_function_calls(gl_shader_program *prog, gl_linked_shader
> > *main,
> >  		    gl_shader **shader_list, unsigned num_shaders)
> >  {
> >     call_link_visitor v(prog, main, shader_list, num_shaders);
> > diff --git a/src/compiler/glsl/link_interface_blocks.cpp
> > b/src/compiler/glsl/link_interface_blocks.cpp
> > index 5858eee..447d9a4 100644
> > --- a/src/compiler/glsl/link_interface_blocks.cpp
> > +++ b/src/compiler/glsl/link_interface_blocks.cpp
> > @@ -343,8 +343,8 @@ validate_intrastage_interface_blocks(struct
> > gl_shader_program *prog,
> >  
> >  void
> >  validate_interstage_inout_blocks(struct gl_shader_program *prog,
> > -                                 const gl_shader *producer,
> > -                                 const gl_shader *consumer)
> > +                                 const gl_linked_shader *producer,
> > +                                 const gl_linked_shader *consumer)
> >  {
> >     interface_block_definitions definitions;
> >     /* VS -> GS, VS -> TCS, VS -> TES, TES -> GS */
> > @@ -384,15 +384,15 @@ validate_interstage_inout_blocks(struct
> > gl_shader_program *prog,
> >  
> >  void
> >  validate_interstage_uniform_blocks(struct gl_shader_program *prog,
> > -                                   gl_shader **stages, int
> > num_stages)
> > +                                   gl_linked_shader **stages)
> >  {
> >     interface_block_definitions definitions;
> >  
> > -   for (int i = 0; i < num_stages; i++) {
> > +   for (int i = 0; i < MESA_SHADER_STAGES; i++) {
> >        if (stages[i] == NULL)
> >           continue;
> >  
> > -      const gl_shader *stage = stages[i];
> > +      const gl_linked_shader *stage = stages[i];
> >        foreach_in_list(ir_instruction, node, stage->ir) {
> >           ir_variable *var = node->as_variable();
> >           if (!var || !var->get_interface_type() ||
> > diff --git a/src/compiler/glsl/link_uniform_blocks.cpp
> > b/src/compiler/glsl/link_uniform_blocks.cpp
> > index b816dab..4b51d40 100644
> > --- a/src/compiler/glsl/link_uniform_blocks.cpp
> > +++ b/src/compiler/glsl/link_uniform_blocks.cpp
> > @@ -391,7 +391,7 @@ void
> >  link_uniform_blocks(void *mem_ctx,
> >                      struct gl_context *ctx,
> >                      struct gl_shader_program *prog,
> > -                    struct gl_shader **shader_list,
> > +                    struct gl_linked_shader **shader_list,
> >                      unsigned num_shaders,
> >                      struct gl_uniform_block **ubo_blocks,
> >                      unsigned *num_ubo_blocks,
> > diff --git a/src/compiler/glsl/link_uniform_initializers.cpp
> > b/src/compiler/glsl/link_uniform_initializers.cpp
> > index acf8222..effbb6a 100644
> > --- a/src/compiler/glsl/link_uniform_initializers.cpp
> > +++ b/src/compiler/glsl/link_uniform_initializers.cpp
> > @@ -131,7 +131,7 @@ set_opaque_binding(void *mem_ctx,
> > gl_shader_program *prog,
> >        }
> >  
> >        for (int sh = 0; sh < MESA_SHADER_STAGES; sh++) {
> > -        gl_shader *shader = prog->_LinkedShaders[sh];
> > +        gl_linked_shader *shader = prog->_LinkedShaders[sh];
> >  
> >           if (shader) {
> >              if (storage->type->base_type == GLSL_TYPE_SAMPLER &&
> > @@ -243,7 +243,7 @@ set_uniform_initializer(void *mem_ctx,
> > gl_shader_program *prog,
> >  
> >        if (storage->type->is_sampler()) {
> >           for (int sh = 0; sh < MESA_SHADER_STAGES; sh++) {
> > -            gl_shader *shader = prog->_LinkedShaders[sh];
> > +            gl_linked_shader *shader = prog->_LinkedShaders[sh];
> >  
> >              if (shader && storage->opaque[sh].active) {
> >                 unsigned index = storage->opaque[sh].index;
> > @@ -263,7 +263,7 @@ link_set_uniform_initializers(struct
> > gl_shader_program *prog,
> >     void *mem_ctx = NULL;
> >  
> >     for (unsigned int i = 0; i < MESA_SHADER_STAGES; i++) {
> > -      struct gl_shader *shader = prog->_LinkedShaders[i];
> > +      struct gl_linked_shader *shader = prog->_LinkedShaders[i];
> >  
> >        if (shader == NULL)
> >  	 continue;
> > diff --git a/src/compiler/glsl/link_uniforms.cpp
> > b/src/compiler/glsl/link_uniforms.cpp
> > index 98ae3ad..807a8f3 100644
> > --- a/src/compiler/glsl/link_uniforms.cpp
> > +++ b/src/compiler/glsl/link_uniforms.cpp
> > @@ -886,7 +886,7 @@ public:
> >   * shaders).
> >   */
> >  static void
> > -link_update_uniform_buffer_variables(struct gl_shader *shader)
> > +link_update_uniform_buffer_variables(struct gl_linked_shader
> > *shader)
> >  {
> >     foreach_in_list(ir_instruction, node, shader->ir) {
> >        ir_variable *const var = node->as_variable();
> > @@ -1022,7 +1022,7 @@ link_assign_uniform_locations(struct
> > gl_shader_program *prog,
> >     struct string_to_uint_map *hiddenUniforms = new
> > string_to_uint_map;
> >     count_uniform_size uniform_size(prog->UniformHash,
> > hiddenUniforms);
> >     for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
> > -      struct gl_shader *sh = prog->_LinkedShaders[i];
> > +      struct gl_linked_shader *sh = prog->_LinkedShaders[i];
> >  
> >        if (sh == NULL)
> >           continue;
> > @@ -1204,7 +1204,7 @@ link_assign_uniform_locations(struct
> > gl_shader_program *prog,
> >           continue;
> >  
> >        for (unsigned j = 0; j < MESA_SHADER_STAGES; j++) {
> > -         struct gl_shader *sh = prog->_LinkedShaders[j];
> > +         struct gl_linked_shader *sh = prog->_LinkedShaders[j];
> >           if (!sh)
> >              continue;
> >  
> > @@ -1234,7 +1234,7 @@ link_assign_uniform_locations(struct
> > gl_shader_program *prog,
> >        if (uniforms[i].remap_location != UNMAPPED_UNIFORM_LOC)
> >           continue;
> >        for (unsigned j = 0; j < MESA_SHADER_STAGES; j++) {
> > -         struct gl_shader *sh = prog->_LinkedShaders[j];
> > +         struct gl_linked_shader *sh = prog->_LinkedShaders[j];
> >           if (!sh)
> >              continue;
> >  
> > diff --git a/src/compiler/glsl/link_varyings.cpp
> > b/src/compiler/glsl/link_varyings.cpp
> > index ef8bdbe..db42bb1 100644
> > --- a/src/compiler/glsl/link_varyings.cpp
> > +++ b/src/compiler/glsl/link_varyings.cpp
> > @@ -107,7 +107,7 @@ create_xfb_varying_names(void *mem_ctx, const
> > glsl_type *t, char **name,
> >  }
> >  
> >  bool
> > -process_xfb_layout_qualifiers(void *mem_ctx, const gl_shader *sh,
> > +process_xfb_layout_qualifiers(void *mem_ctx, const
> > gl_linked_shader *sh,
> >                                unsigned *num_tfeedback_decls,
> >                                char ***varying_names)
> >  {
> > @@ -370,7 +370,8 @@ cross_validate_front_and_back_color(struct
> > gl_shader_program *prog,
> >   */
> >  void
> >  cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
> > -                                 gl_shader *producer, gl_shader
> > *consumer)
> > +                                 gl_linked_shader *producer,
> > +                                 gl_linked_shader *consumer)
> >  {
> >     glsl_symbol_table parameters;
> >     ir_variable *explicit_locations[MAX_VARYINGS_INCL_PATCH][4] =
> > @@ -556,7 +557,7 @@ cross_validate_outputs_to_inputs(struct
> > gl_shader_program *prog,
> >   */
> >  void
> >  remove_unused_shader_inputs_and_outputs(bool
> > is_separate_shader_object,
> > -                                        gl_shader *sh,
> > +                                        gl_linked_shader *sh,
> >                                          enum ir_variable_mode
> > mode)
> >  {
> >     if (is_separate_shader_object)
> > @@ -1938,7 +1939,8 @@ canonicalize_shader_io(exec_list *ir, enum
> > ir_variable_mode io_mode)
> >   * with a max of MAX_VARYING.
> >   */
> >  uint64_t
> > -reserved_varying_slot(struct gl_shader *stage, ir_variable_mode
> > io_mode)
> > +reserved_varying_slot(struct gl_linked_shader *stage,
> > +                      ir_variable_mode io_mode)
> >  {
> >     assert(io_mode == ir_var_shader_in || io_mode ==
> > ir_var_shader_out);
> >     /* Avoid an overflow of the returned value */
> > @@ -1997,7 +1999,8 @@ bool
> >  assign_varying_locations(struct gl_context *ctx,
> >                           void *mem_ctx,
> >                           struct gl_shader_program *prog,
> > -                         gl_shader *producer, gl_shader *consumer,
> > +                         gl_linked_shader *producer,
> > +                         gl_linked_shader *consumer,
> >                           unsigned num_tfeedback_decls,
> >                           tfeedback_decl *tfeedback_decls,
> >                           const uint64_t reserved_slots)
> > @@ -2260,7 +2263,7 @@ assign_varying_locations(struct gl_context
> > *ctx,
> >  bool
> >  check_against_output_limit(struct gl_context *ctx,
> >                             struct gl_shader_program *prog,
> > -                           gl_shader *producer,
> > +                           gl_linked_shader *producer,
> >                             unsigned num_explicit_locations)
> >  {
> >     unsigned output_vectors = num_explicit_locations;
> > @@ -2304,7 +2307,7 @@ check_against_output_limit(struct gl_context
> > *ctx,
> >  bool
> >  check_against_input_limit(struct gl_context *ctx,
> >                            struct gl_shader_program *prog,
> > -                          gl_shader *consumer,
> > +                          gl_linked_shader *consumer,
> >                            unsigned num_explicit_locations)
> >  {
> >     unsigned input_vectors = num_explicit_locations;
> > diff --git a/src/compiler/glsl/link_varyings.h
> > b/src/compiler/glsl/link_varyings.h
> > index 39e9070..afce56e 100644
> > --- a/src/compiler/glsl/link_varyings.h
> > +++ b/src/compiler/glsl/link_varyings.h
> > @@ -291,7 +291,8 @@ private:
> >  
> >  void
> >  cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
> > -				 gl_shader *producer, gl_shader
> > *consumer);
> > +                                 gl_linked_shader *producer,
> > +                                 gl_linked_shader *consumer);
> >  
> >  bool
> >  parse_tfeedback_decls(struct gl_context *ctx, struct
> > gl_shader_program *prog,
> > @@ -299,13 +300,13 @@ parse_tfeedback_decls(struct gl_context *ctx,
> > struct gl_shader_program *prog,
> >                        char **varying_names, tfeedback_decl
> > *decls);
> >  
> >  bool
> > -process_xfb_layout_qualifiers(void *mem_ctx, const gl_shader *sh,
> > +process_xfb_layout_qualifiers(void *mem_ctx, const
> > gl_linked_shader *sh,
> >                                unsigned *num_tfeedback_decls,
> >                                char ***varying_names);
> >  
> >  void
> >  remove_unused_shader_inputs_and_outputs(bool
> > is_separate_shader_object,
> > -                                        gl_shader *sh,
> > +                                        gl_linked_shader *sh,
> >                                          enum ir_variable_mode
> > mode);
> >  
> >  bool
> > @@ -318,24 +319,26 @@ bool
> >  assign_varying_locations(struct gl_context *ctx,
> >  			 void *mem_ctx,
> >  			 struct gl_shader_program *prog,
> > -			 gl_shader *producer, gl_shader *consumer,
> > +                         gl_linked_shader *producer,
> > +                         gl_linked_shader *consumer,
> >                           unsigned num_tfeedback_decls,
> >                           tfeedback_decl *tfeedback_decls,
> >                           const uint64_t reserved_slots);
> >  
> >  uint64_t
> > -reserved_varying_slot(struct gl_shader *stage, ir_variable_mode
> > io_mode);
> > +reserved_varying_slot(struct gl_linked_shader *stage,
> > +                      ir_variable_mode io_mode);
> >  
> >  bool
> >  check_against_output_limit(struct gl_context *ctx,
> >                             struct gl_shader_program *prog,
> > -                           gl_shader *producer,
> > +                           gl_linked_shader *producer,
> >                             unsigned num_explicit_locations);
> >  
> >  bool
> >  check_against_input_limit(struct gl_context *ctx,
> >                            struct gl_shader_program *prog,
> > -                          gl_shader *consumer,
> > +                          gl_linked_shader *consumer,
> >                            unsigned num_explicit_locations);
> >  
> >  #endif /* GLSL_LINK_VARYINGS_H */
> > diff --git a/src/compiler/glsl/linker.cpp
> > b/src/compiler/glsl/linker.cpp
> > index 411d2fe..926520e 100644
> > --- a/src/compiler/glsl/linker.cpp
> > +++ b/src/compiler/glsl/linker.cpp
> > @@ -655,7 +655,7 @@ link_invalidate_variable_locations(exec_list
> > *ir)
> >   */
> >  static void
> >  analyze_clip_cull_usage(struct gl_shader_program *prog,
> > -                        struct gl_shader *shader,
> > +                        struct gl_linked_shader *shader,
> >                          struct gl_context *ctx,
> >                          GLuint *clip_distance_array_size,
> >                          GLuint *cull_distance_array_size)
> > @@ -750,7 +750,7 @@ analyze_clip_cull_usage(struct
> > gl_shader_program *prog,
> >   */
> >  void
> >  validate_vertex_shader_executable(struct gl_shader_program *prog,
> > -                                  struct gl_shader *shader,
> > +                                  struct gl_linked_shader *shader,
> >                                    struct gl_context *ctx)
> >  {
> >     if (shader == NULL)
> > @@ -805,7 +805,7 @@ validate_vertex_shader_executable(struct
> > gl_shader_program *prog,
> >  
> >  void
> >  validate_tess_eval_shader_executable(struct gl_shader_program
> > *prog,
> > -                                     struct gl_shader *shader,
> > +                                     struct gl_linked_shader
> > *shader,
> >                                       struct gl_context *ctx)
> >  {
> >     if (shader == NULL)
> > @@ -824,7 +824,7 @@ validate_tess_eval_shader_executable(struct
> > gl_shader_program *prog,
> >   */
> >  void
> >  validate_fragment_shader_executable(struct gl_shader_program
> > *prog,
> > -                                    struct gl_shader *shader)
> > +                                    struct gl_linked_shader
> > *shader)
> >  {
> >     if (shader == NULL)
> >        return;
> > @@ -851,7 +851,7 @@ validate_fragment_shader_executable(struct
> > gl_shader_program *prog,
> >   */
> >  void
> >  validate_geometry_shader_executable(struct gl_shader_program
> > *prog,
> > -                                    struct gl_shader *shader,
> > +                                    struct gl_linked_shader
> > *shader,
> >                                      struct gl_context *ctx)
> >  {
> >     if (shader == NULL)
> > @@ -873,7 +873,7 @@ static void
> >  validate_geometry_shader_emissions(struct gl_context *ctx,
> >                                     struct gl_shader_program *prog)
> >  {
> > -   struct gl_shader *sh = prog-
> > >_LinkedShaders[MESA_SHADER_GEOMETRY];
> > +   struct gl_linked_shader *sh = prog-
> > >_LinkedShaders[MESA_SHADER_GEOMETRY];
> >  
> >     if (sh != NULL) {
> >        find_emit_vertex_visitor emit_vertex(ctx-
> > >Const.MaxVertexStreams - 1);
> > @@ -1240,7 +1240,7 @@
> > interstage_cross_validate_uniform_blocks(struct gl_shader_program
> > *prog,
> >     }
> >  
> >     for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
> > -      struct gl_shader *sh = prog->_LinkedShaders[i];
> > +      struct gl_linked_shader *sh = prog->_LinkedShaders[i];
> >  
> >        InterfaceBlockStageIndex[i] = new
> > int[max_num_buffer_blocks];
> >        for (unsigned int j = 0; j < max_num_buffer_blocks; j++)
> > @@ -1285,7 +1285,7 @@
> > interstage_cross_validate_uniform_blocks(struct gl_shader_program
> > *prog,
> >           int stage_index = InterfaceBlockStageIndex[i][j];
> >  
> >  	 if (stage_index != -1) {
> > -	    struct gl_shader *sh = prog->_LinkedShaders[i];
> > +	    struct gl_linked_shader *sh = prog->_LinkedShaders[i];
> >  
> >              blks[j].stageref |= (1 << i);
> >  
> > @@ -1314,7 +1314,7 @@
> > interstage_cross_validate_uniform_blocks(struct gl_shader_program
> > *prog,
> >   * Populates a shaders symbol table with all global declarations
> >   */
> >  static void
> > -populate_symbol_table(gl_shader *sh)
> > +populate_symbol_table(gl_linked_shader *sh)
> >  {
> >     sh->symbols = new(sh) glsl_symbol_table;
> >  
> > @@ -1352,12 +1352,12 @@ populate_symbol_table(gl_shader *sh)
> >   *                     should be added.
> >   */
> >  void
> > -remap_variables(ir_instruction *inst, struct gl_shader *target,
> > +remap_variables(ir_instruction *inst, struct gl_linked_shader
> > *target,
> >  		hash_table *temps)
> >  {
> >     class remap_visitor : public ir_hierarchical_visitor {
> >     public:
> > -	 remap_visitor(struct gl_shader *target,
> > +	 remap_visitor(struct gl_linked_shader *target,
> >  		    hash_table *temps)
> >        {
> >  	 this->target = target;
> > @@ -1392,7 +1392,7 @@ remap_variables(ir_instruction *inst, struct
> > gl_shader *target,
> >        }
> >  
> >     private:
> > -      struct gl_shader *target;
> > +      struct gl_linked_shader *target;
> >        glsl_symbol_table *symbols;
> >        exec_list *instructions;
> >        hash_table *temps;
> > @@ -1427,7 +1427,7 @@ remap_variables(ir_instruction *inst, struct
> > gl_shader *target,
> >   */
> >  exec_node *
> >  move_non_declarations(exec_list *instructions, exec_node *last,
> > -		      bool make_copies, gl_shader *target)
> > +		      bool make_copies, gl_linked_shader *target)
> >  {
> >     hash_table *temps = NULL;
> >  
> > @@ -1682,7 +1682,7 @@ private:
> >  static void
> >  link_xfb_stride_layout_qualifiers(struct gl_context *ctx,
> >                                    struct gl_shader_program *prog,
> > -			          struct gl_shader *linked_shader,
> > +			          struct gl_linked_shader
> > *linked_shader,
> >  			          struct gl_shader **shader_list,
> >  			          unsigned num_shaders)
> >  {
> > @@ -1746,7 +1746,7 @@ link_xfb_stride_layout_qualifiers(struct
> > gl_context *ctx,
> >   */
> >  static void
> >  link_tcs_out_layout_qualifiers(struct gl_shader_program *prog,
> > -			      struct gl_shader *linked_shader,
> > +			      struct gl_linked_shader
> > *linked_shader,
> >  			      struct gl_shader **shader_list,
> >  			      unsigned num_shaders)
> >  {
> > @@ -1801,7 +1801,7 @@ link_tcs_out_layout_qualifiers(struct
> > gl_shader_program *prog,
> >   */
> >  static void
> >  link_tes_in_layout_qualifiers(struct gl_shader_program *prog,
> > -				struct gl_shader *linked_shader,
> > +				struct gl_linked_shader
> > *linked_shader,
> >  				struct gl_shader **shader_list,
> >  				unsigned num_shaders)
> >  {
> > @@ -1901,7 +1901,7 @@ link_tes_in_layout_qualifiers(struct
> > gl_shader_program *prog,
> >   */
> >  static void
> >  link_fs_input_layout_qualifiers(struct gl_shader_program *prog,
> > -	                        struct gl_shader *linked_shader,
> > +	                        struct gl_linked_shader
> > *linked_shader,
> >  	                        struct gl_shader **shader_list,
> >  	                        unsigned num_shaders)
> >  {
> > @@ -1969,7 +1969,7 @@ link_fs_input_layout_qualifiers(struct
> > gl_shader_program *prog,
> >   */
> >  static void
> >  link_gs_inout_layout_qualifiers(struct gl_shader_program *prog,
> > -				struct gl_shader *linked_shader,
> > +				struct gl_linked_shader
> > *linked_shader,
> >  				struct gl_shader **shader_list,
> >  				unsigned num_shaders)
> >  {
> > @@ -2076,7 +2076,7 @@ link_gs_inout_layout_qualifiers(struct
> > gl_shader_program *prog,
> >   */
> >  static void
> >  link_cs_input_layout_qualifiers(struct gl_shader_program *prog,
> > -                                struct gl_shader *linked_shader,
> > +                                struct gl_linked_shader
> > *linked_shader,
> >                                  struct gl_shader **shader_list,
> >                                  unsigned num_shaders)
> >  {
> > @@ -2138,7 +2138,7 @@ link_cs_input_layout_qualifiers(struct
> > gl_shader_program *prog,
> >   * If this function is supplied a single shader, it is cloned, and
> > the new
> >   * shader is returned.
> >   */
> > -static struct gl_shader *
> > +static struct gl_linked_shader *
> >  link_intrastage_shaders(void *mem_ctx,
> >  			struct gl_context *ctx,
> >  			struct gl_shader_program *prog,
> > @@ -2216,7 +2216,7 @@ link_intrastage_shaders(void *mem_ctx,
> >      */
> >     gl_shader *main = NULL;
> >     for (unsigned i = 0; i < num_shaders; i++) {
> > -      if (!_mesa_get_main_function_signature(shader_list[i]-
> > >symbols)) {
> > +      if (_mesa_get_main_function_signature(shader_list[i]-
> > >symbols)) {
> >  	 main = shader_list[i];
> >  	 break;
> >        }
> > @@ -2228,7 +2228,7 @@ link_intrastage_shaders(void *mem_ctx,
> >        return NULL;
> >     }
> >  
> > -   gl_shader *linked = ctx->Driver.NewShader(NULL, 0,
> > shader_list[0]->Stage);
> > +   gl_linked_shader *linked = ctx-
> > >Driver.NewShader(shader_list[0]->Stage);
> >     linked->ir = new(linked) exec_list;
> >     clone_ir_list(mem_ctx, linked->ir, main->ir);
> >  
> > @@ -2299,7 +2299,7 @@ link_intrastage_shaders(void *mem_ctx,
> >  
> > 
> >     if (!ok) {
> > -      _mesa_delete_shader(ctx, linked);
> > +      _mesa_delete_linked_shader(ctx, linked);
> >        return NULL;
> >     }
> >  
> > @@ -2317,7 +2317,7 @@ link_intrastage_shaders(void *mem_ctx,
> >                         &num_ssbo_blocks);
> >  
> >     if (!prog->LinkStatus) {
> > -      _mesa_delete_shader(ctx, linked);
> > +      _mesa_delete_linked_shader(ctx, linked);
> >        return NULL;
> >     }
> >  
> > @@ -2463,8 +2463,8 @@ resize_tes_inputs(struct gl_context *ctx,
> >     if (prog->_LinkedShaders[MESA_SHADER_TESS_EVAL] == NULL)
> >        return;
> >  
> > -   gl_shader *const tcs = prog-
> > >_LinkedShaders[MESA_SHADER_TESS_CTRL];
> > -   gl_shader *const tes = prog-
> > >_LinkedShaders[MESA_SHADER_TESS_EVAL];
> > +   gl_linked_shader *const tcs = prog-
> > >_LinkedShaders[MESA_SHADER_TESS_CTRL];
> > +   gl_linked_shader *const tes = prog-
> > >_LinkedShaders[MESA_SHADER_TESS_EVAL];
> >  
> >     /* If no control shader is present, then the TES inputs are
> > statically
> >      * sized to MaxPatchVertices; the actual size of the arrays
> > won't be
> > @@ -2576,7 +2576,7 @@
> > assign_attribute_or_color_locations(gl_shader_program *prog,
> >     assert((target_index == MESA_SHADER_VERTEX)
> >  	  || (target_index == MESA_SHADER_FRAGMENT));
> >  
> > -   gl_shader *const sh = prog->_LinkedShaders[target_index];
> > +   gl_linked_shader *const sh = prog-
> > >_LinkedShaders[target_index];
> >     if (sh == NULL)
> >        return true;
> >  
> > @@ -2976,8 +2976,8 @@
> > assign_attribute_or_color_locations(gl_shader_program *prog,
> >   * unmatch flag if found so we don't optimise them away.
> >   */
> >  static void
> > -match_explicit_outputs_to_inputs(gl_shader *producer,
> > -                                 gl_shader *consumer)
> > +match_explicit_outputs_to_inputs(gl_linked_shader *producer,
> > +                                 gl_linked_shader *consumer)
> >  {
> >     glsl_symbol_table parameters;
> >     ir_variable *explicit_locations[MAX_VARYINGS_INCL_PATCH][4] =
> > @@ -3081,7 +3081,7 @@ check_resources(struct gl_context *ctx,
> > struct gl_shader_program *prog)
> >     unsigned total_shader_storage_blocks = 0;
> >  
> >     for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
> > -      struct gl_shader *sh = prog->_LinkedShaders[i];
> > +      struct gl_linked_shader *sh = prog->_LinkedShaders[i];
> >  
> >        if (sh == NULL)
> >  	 continue;
> > @@ -3175,7 +3175,7 @@ static void
> >  link_calculate_subroutine_compat(struct gl_shader_program *prog)
> >  {
> >     for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
> > -      struct gl_shader *sh = prog->_LinkedShaders[i];
> > +      struct gl_linked_shader *sh = prog->_LinkedShaders[i];
> >        int count;
> >        if (!sh)
> >           continue;
> > @@ -3213,7 +3213,7 @@ static void
> >  check_subroutine_resources(struct gl_shader_program *prog)
> >  {
> >     for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
> > -      struct gl_shader *sh = prog->_LinkedShaders[i];
> > +      struct gl_linked_shader *sh = prog->_LinkedShaders[i];
> >  
> >        if (sh) {
> >           if (sh->NumSubroutineUniformRemapTable >
> > MAX_SUBROUTINE_UNIFORM_LOCATIONS)
> > @@ -3236,7 +3236,7 @@ check_image_resources(struct gl_context *ctx,
> > struct gl_shader_program *prog)
> >        return;
> >  
> >     for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
> > -      struct gl_shader *sh = prog->_LinkedShaders[i];
> > +      struct gl_linked_shader *sh = prog->_LinkedShaders[i];
> >  
> >        if (sh) {
> >           if (sh->NumImages > ctx-
> > >Const.Program[i].MaxImageUniforms)
> > @@ -3340,7 +3340,7 @@ reserve_explicit_locations(struct
> > gl_shader_program *prog,
> >  
> >  static bool
> >  reserve_subroutine_explicit_locations(struct gl_shader_program
> > *prog,
> > -                                      struct gl_shader *sh,
> > +                                      struct gl_linked_shader *sh,
> >                                        ir_variable *var)
> >  {
> >     unsigned slots = var->type->uniform_locations();
> > @@ -3415,7 +3415,7 @@ check_explicit_uniform_locations(struct
> > gl_context *ctx,
> >  
> >     unsigned entries_total = 0;
> >     for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
> > -      struct gl_shader *sh = prog->_LinkedShaders[i];
> > +      struct gl_linked_shader *sh = prog->_LinkedShaders[i];
> >  
> >        if (!sh)
> >           continue;
> > @@ -3620,7 +3620,7 @@ build_stageref(struct gl_shader_program
> > *shProg, const char *name,
> >     assert(MESA_SHADER_STAGES < 8);
> >  
> >     for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
> > -      struct gl_shader *sh = shProg->_LinkedShaders[i];
> > +      struct gl_linked_shader *sh = shProg->_LinkedShaders[i];
> >        if (!sh)
> >           continue;
> >  
> > @@ -3859,7 +3859,7 @@ add_interface_variables(struct
> > gl_shader_program *shProg,
> >  static bool
> >  add_packed_varyings(struct gl_shader_program *shProg, int stage,
> > GLenum type)
> >  {
> > -   struct gl_shader *sh = shProg->_LinkedShaders[stage];
> > +   struct gl_linked_shader *sh = shProg->_LinkedShaders[stage];
> >     GLenum iface;
> >  
> >     if (!sh || !sh->packed_varyings)
> > @@ -3895,7 +3895,7 @@ add_packed_varyings(struct gl_shader_program
> > *shProg, int stage, GLenum type)
> >  static bool
> >  add_fragdata_arrays(struct gl_shader_program *shProg)
> >  {
> > -   struct gl_shader *sh = shProg-
> > >_LinkedShaders[MESA_SHADER_FRAGMENT];
> > +   struct gl_linked_shader *sh = shProg-
> > >_LinkedShaders[MESA_SHADER_FRAGMENT];
> >  
> >     if (!sh || !sh->fragdata_arrays)
> >        return true;
> > @@ -4270,7 +4270,7 @@ build_program_resource_list(struct gl_context
> > *ctx,
> >     }
> >  
> >     for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
> > -      struct gl_shader *sh = shProg->_LinkedShaders[i];
> > +      struct gl_linked_shader *sh = shProg->_LinkedShaders[i];
> >        GLuint type;
> >  
> >        if (!sh)
> > @@ -4322,7 +4322,7 @@ static void
> >  link_assign_subroutine_types(struct gl_shader_program *prog)
> >  {
> >     for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
> > -      gl_shader *sh = prog->_LinkedShaders[i];
> > +      gl_linked_shader *sh = prog->_LinkedShaders[i];
> >  
> >        if (sh == NULL)
> >           continue;
> > @@ -4428,7 +4428,7 @@ disable_varying_optimizations_for_sso(struct
> > gl_shader_program *prog)
> >        return;
> >  
> >     for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) {
> > -      gl_shader *sh = prog->_LinkedShaders[stage];
> > +      gl_linked_shader *sh = prog->_LinkedShaders[stage];
> >        if (!sh)
> >           continue;
> >  
> > @@ -4587,8 +4587,9 @@ link_shaders(struct gl_context *ctx, struct
> > gl_shader_program *prog)
> >     }
> >  
> >     for (unsigned int i = 0; i < MESA_SHADER_STAGES; i++) {
> > -      if (prog->_LinkedShaders[i] != NULL)
> > -	 _mesa_delete_shader(ctx, prog->_LinkedShaders[i]);
> > +      if (prog->_LinkedShaders[i] != NULL) {
> > +	 _mesa_delete_linked_shader(ctx, prog->_LinkedShaders[i]);
> > +      }
> >  
> >        prog->_LinkedShaders[i] = NULL;
> >     }
> > @@ -4597,13 +4598,13 @@ link_shaders(struct gl_context *ctx, struct
> > gl_shader_program *prog)
> >      */
> >     for (int stage = 0; stage < MESA_SHADER_STAGES; stage++) {
> >        if (num_shaders[stage] > 0) {
> > -         gl_shader *const sh =
> > +         gl_linked_shader *const sh =
> >              link_intrastage_shaders(mem_ctx, ctx, prog,
> > shader_list[stage],
> >                                      num_shaders[stage]);
> >  
> >           if (!prog->LinkStatus) {
> >              if (sh)
> > -               _mesa_delete_shader(ctx, sh);
> > +               _mesa_delete_linked_shader(ctx, sh);
> >              goto done;
> >           }
> >  
> > @@ -4626,11 +4627,11 @@ link_shaders(struct gl_context *ctx, struct
> > gl_shader_program *prog)
> >           }
> >           if (!prog->LinkStatus) {
> >              if (sh)
> > -               _mesa_delete_shader(ctx, sh);
> > +               _mesa_delete_linked_shader(ctx, sh);
> >              goto done;
> >           }
> >  
> > -         _mesa_reference_shader(ctx, &prog->_LinkedShaders[stage], 
> > sh);
> > +         prog->_LinkedShaders[stage] = sh;
> >        }
> >     }
> >  
> > @@ -4701,8 +4702,7 @@ link_shaders(struct gl_context *ctx, struct
> > gl_shader_program *prog)
> >     }
> >  
> >     /* Cross-validate uniform blocks between shader stages */
> > -   validate_interstage_uniform_blocks(prog, prog->_LinkedShaders,
> > -                                      MESA_SHADER_STAGES);
> > +   validate_interstage_uniform_blocks(prog, prog->_LinkedShaders);
> >     if (!prog->LinkStatus)
> >        goto done;
> >  
> > @@ -4718,7 +4718,7 @@ link_shaders(struct gl_context *ctx, struct
> > gl_shader_program *prog)
> >      * This rule also applies to GLSL ES 3.00.
> >      */
> >     if (max_version >= (prog->IsES ? 300 : 130)) {
> > -      struct gl_shader *sh = prog-
> > >_LinkedShaders[MESA_SHADER_FRAGMENT];
> > +      struct gl_linked_shader *sh = prog-
> > >_LinkedShaders[MESA_SHADER_FRAGMENT];
> >        if (sh) {
> >  	 lower_discard_flow(sh->ir);
> >        }
> > @@ -4879,7 +4879,7 @@ link_shaders(struct gl_context *ctx, struct
> > gl_shader_program *prog)
> >        /* If the program is made up of only a single stage */
> >        if (first == last) {
> >  
> > -         gl_shader *const sh = prog->_LinkedShaders[last];
> > +         gl_linked_shader *const sh = prog->_LinkedShaders[last];
> >           if (prog->SeparateShader) {
> >              const uint64_t reserved_slots =
> >                 reserved_varying_slot(sh, ir_var_shader_in);
> > @@ -4910,8 +4910,8 @@ link_shaders(struct gl_context *ctx, struct
> > gl_shader_program *prog)
> >              if (prog->_LinkedShaders[i] == NULL && i != 0)
> >                 continue;
> >  
> > -            gl_shader *const sh_i = prog->_LinkedShaders[i];
> > -            gl_shader *const sh_next = prog->_LinkedShaders[next];
> > +            gl_linked_shader *const sh_i = prog-
> > >_LinkedShaders[i];
> > +            gl_linked_shader *const sh_next = prog-
> > >_LinkedShaders[next];
> >  
> >              const uint64_t reserved_out_slots =
> >                 reserved_varying_slot(sh_i, ir_var_shader_out);
> > diff --git a/src/compiler/glsl/linker.h
> > b/src/compiler/glsl/linker.h
> > index 045dc1f..19b14d5 100644
> > --- a/src/compiler/glsl/linker.h
> > +++ b/src/compiler/glsl/linker.h
> > @@ -27,7 +27,7 @@
> >  #define GLSL_LINKER_H
> >  
> >  extern bool
> > -link_function_calls(gl_shader_program *prog, gl_shader *main,
> > +link_function_calls(gl_shader_program *prog, gl_linked_shader
> > *main,
> >  		    gl_shader **shader_list, unsigned
> > num_shaders);
> >  
> >  extern void
> > @@ -57,7 +57,7 @@ extern void
> >  link_uniform_blocks(void *mem_ctx,
> >                      struct gl_context *ctx,
> >                      struct gl_shader_program *prog,
> > -                    struct gl_shader **shader_list,
> > +                    struct gl_linked_shader **shader_list,
> >                      unsigned num_shaders,
> >                      struct gl_uniform_block **ubo_blocks,
> >                      unsigned *num_ubo_blocks,
> > @@ -76,12 +76,12 @@ validate_intrastage_interface_blocks(struct
> > gl_shader_program *prog,
> >  
> >  void
> >  validate_interstage_inout_blocks(struct gl_shader_program *prog,
> > -                                 const gl_shader *producer,
> > -                                 const gl_shader *consumer);
> > +                                 const gl_linked_shader *producer,
> > +                                 const gl_linked_shader
> > *consumer);
> >  
> >  void
> >  validate_interstage_uniform_blocks(struct gl_shader_program *prog,
> > -                                   gl_shader **stages, int
> > num_stages);
> > +                                   gl_linked_shader **stages);
> >  
> >  extern void
> >  link_assign_atomic_counter_resources(struct gl_context *ctx,
> > diff --git a/src/compiler/glsl/lower_distance.cpp
> > b/src/compiler/glsl/lower_distance.cpp
> > index c2158f2..e2d7e2a 100644
> > --- a/src/compiler/glsl/lower_distance.cpp
> > +++ b/src/compiler/glsl/lower_distance.cpp
> > @@ -654,7 +654,8 @@
> > lower_distance_visitor_counter::handle_rvalue(ir_rvalue **rv)
> >  }
> >  
> >  bool
> > -lower_clip_cull_distance(struct gl_shader_program *prog, gl_shader
> > *shader)
> > +lower_clip_cull_distance(struct gl_shader_program *prog,
> > +                         struct gl_linked_shader *shader)
> >  {
> >     int clip_size, cull_size;
> >  
> > diff --git a/src/compiler/glsl/lower_named_interface_blocks.cpp
> > b/src/compiler/glsl/lower_named_interface_blocks.cpp
> > index f780eca..dbf0c63 100644
> > --- a/src/compiler/glsl/lower_named_interface_blocks.cpp
> > +++ b/src/compiler/glsl/lower_named_interface_blocks.cpp
> > @@ -289,7 +289,7 @@
> > flatten_named_interface_blocks_declarations::handle_rvalue(ir_rvalu
> > e **rvalue)
> >  }
> >  
> >  void
> > -lower_named_interface_blocks(void *mem_ctx, gl_shader *shader)
> > +lower_named_interface_blocks(void *mem_ctx, gl_linked_shader
> > *shader)
> >  {
> >     flatten_named_interface_blocks_declarations v_decl(mem_ctx);
> >     v_decl.run(shader->ir);
> > diff --git a/src/compiler/glsl/lower_packed_varyings.cpp
> > b/src/compiler/glsl/lower_packed_varyings.cpp
> > index 130b8f6..a897d2f 100644
> > --- a/src/compiler/glsl/lower_packed_varyings.cpp
> > +++ b/src/compiler/glsl/lower_packed_varyings.cpp
> > @@ -172,7 +172,7 @@ public:
> >                                   bool disable_varying_packing,
> >                                   bool xfb_enabled);
> >  
> > -   void run(struct gl_shader *shader);
> > +   void run(struct gl_linked_shader *shader);
> >  
> >  private:
> >     void bitwise_assign_pack(ir_rvalue *lhs, ir_rvalue *rhs);
> > @@ -260,7 +260,7 @@
> > lower_packed_varyings_visitor::lower_packed_varyings_visitor(
> >  }
> >  
> >  void
> > -lower_packed_varyings_visitor::run(struct gl_shader *shader)
> > +lower_packed_varyings_visitor::run(struct gl_linked_shader
> > *shader)
> >  {
> >     foreach_in_list(ir_instruction, node, shader->ir) {
> >        ir_variable *var = node->as_variable();
> > @@ -767,7 +767,7 @@
> > lower_packed_varyings_return_splicer::visit_leave(ir_return *ret)
> >  void
> >  lower_packed_varyings(void *mem_ctx, unsigned locations_used,
> >                        ir_variable_mode mode, unsigned
> > gs_input_vertices,
> > -                      gl_shader *shader, bool
> > disable_varying_packing,
> > +                      gl_linked_shader *shader, bool
> > disable_varying_packing,
> >                        bool xfb_enabled)
> >  {
> >     exec_list *instructions = shader->ir;
> > diff --git a/src/compiler/glsl/lower_shared_reference.cpp
> > b/src/compiler/glsl/lower_shared_reference.cpp
> > index e63e7dd..1702469 100644
> > --- a/src/compiler/glsl/lower_shared_reference.cpp
> > +++ b/src/compiler/glsl/lower_shared_reference.cpp
> > @@ -51,7 +51,7 @@ class lower_shared_reference_visitor :
> >        public lower_buffer_access::lower_buffer_access {
> >  public:
> >  
> > -   lower_shared_reference_visitor(struct gl_shader *shader)
> > +   lower_shared_reference_visitor(struct gl_linked_shader *shader)
> >        : list_ctx(ralloc_context(NULL)), shader(shader),
> > shared_size(0u)
> >     {
> >        list_inithead(&var_offsets);
> > @@ -88,7 +88,7 @@ public:
> >                           unsigned write_mask);
> >  
> >     void *list_ctx;
> > -   struct gl_shader *shader;
> > +   struct gl_linked_shader *shader;
> >     struct list_head var_offsets;
> >     unsigned shared_size;
> >     bool progress;
> > @@ -475,7 +475,7 @@
> > lower_shared_reference_visitor::visit_enter(ir_call *ir)
> >  } /* unnamed namespace */
> >  
> >  void
> > -lower_shared_reference(struct gl_shader *shader, unsigned
> > *shared_size)
> > +lower_shared_reference(struct gl_linked_shader *shader, unsigned
> > *shared_size)
> >  {
> >     if (shader->Stage != MESA_SHADER_COMPUTE)
> >        return;
> > diff --git a/src/compiler/glsl/lower_tess_level.cpp
> > b/src/compiler/glsl/lower_tess_level.cpp
> > index bed2553..adca29c 100644
> > --- a/src/compiler/glsl/lower_tess_level.cpp
> > +++ b/src/compiler/glsl/lower_tess_level.cpp
> > @@ -440,7 +440,7 @@ lower_tess_level_visitor::visit_leave(ir_call
> > *ir)
> >  
> > 
> >  bool
> > -lower_tess_level(gl_shader *shader)
> > +lower_tess_level(gl_linked_shader *shader)
> >  {
> >     if ((shader->Stage != MESA_SHADER_TESS_CTRL) &&
> >         (shader->Stage != MESA_SHADER_TESS_EVAL))
> > diff --git a/src/compiler/glsl/lower_ubo_reference.cpp
> > b/src/compiler/glsl/lower_ubo_reference.cpp
> > index c27de0b..083f43f 100644
> > --- a/src/compiler/glsl/lower_ubo_reference.cpp
> > +++ b/src/compiler/glsl/lower_ubo_reference.cpp
> > @@ -44,7 +44,7 @@ namespace {
> >  class lower_ubo_reference_visitor :
> >        public lower_buffer_access::lower_buffer_access {
> >  public:
> > -   lower_ubo_reference_visitor(struct gl_shader *shader,
> > +   lower_ubo_reference_visitor(struct gl_linked_shader *shader,
> >                                 bool clamp_block_indices)
> >     : shader(shader), clamp_block_indices(clamp_block_indices),
> >       struct_field(NULL), variable(NULL)
> > @@ -105,7 +105,7 @@ public:
> >     ir_call *check_for_ssbo_atomic_intrinsic(ir_call *ir);
> >     ir_visitor_status visit_enter(ir_call *ir);
> >  
> > -   struct gl_shader *shader;
> > +   struct gl_linked_shader *shader;
> >     bool clamp_block_indices;
> >     struct gl_uniform_buffer_variable *ubo_var;
> >     const struct glsl_struct_field *struct_field;
> > @@ -1090,7 +1090,7 @@
> > lower_ubo_reference_visitor::visit_enter(ir_call *ir)
> >  } /* unnamed namespace */
> >  
> >  void
> > -lower_ubo_reference(struct gl_shader *shader, bool
> > clamp_block_indices)
> > +lower_ubo_reference(struct gl_linked_shader *shader, bool
> > clamp_block_indices)
> >  {
> >     lower_ubo_reference_visitor v(shader, clamp_block_indices);
> >  
> > diff --git a/src/compiler/glsl/lower_vector_derefs.cpp
> > b/src/compiler/glsl/lower_vector_derefs.cpp
> > index 4a5d6f0..f7bf68d 100644
> > --- a/src/compiler/glsl/lower_vector_derefs.cpp
> > +++ b/src/compiler/glsl/lower_vector_derefs.cpp
> > @@ -94,7 +94,7 @@ vector_deref_visitor::handle_rvalue(ir_rvalue
> > **rv)
> >  }
> >  
> >  bool
> > -lower_vector_derefs(gl_shader *shader)
> > +lower_vector_derefs(gl_linked_shader *shader)
> >  {
> >     vector_deref_visitor v;
> >  
> > diff --git a/src/compiler/glsl/lower_vertex_id.cpp
> > b/src/compiler/glsl/lower_vertex_id.cpp
> > index ee69d94..412b97e 100644
> > --- a/src/compiler/glsl/lower_vertex_id.cpp
> > +++ b/src/compiler/glsl/lower_vertex_id.cpp
> > @@ -122,7 +122,7 @@
> > lower_vertex_id_visitor::visit(ir_dereference_variable *ir)
> >  }
> >  
> >  bool
> > -lower_vertex_id(gl_shader *shader)
> > +lower_vertex_id(gl_linked_shader *shader)
> >  {
> >     /* gl_VertexID only exists in the vertex shader.
> >      */
> > diff --git a/src/compiler/glsl/opt_dead_builtin_varyings.cpp
> > b/src/compiler/glsl/opt_dead_builtin_varyings.cpp
> > index 2e40b78..7feea3b 100644
> > --- a/src/compiler/glsl/opt_dead_builtin_varyings.cpp
> > +++ b/src/compiler/glsl/opt_dead_builtin_varyings.cpp
> > @@ -272,7 +272,7 @@ public:
> >   */
> >  class replace_varyings_visitor : public ir_rvalue_visitor {
> >  public:
> > -   replace_varyings_visitor(struct gl_shader *sha,
> > +   replace_varyings_visitor(struct gl_linked_shader *sha,
> >                              const varying_info_visitor *info,
> >                              unsigned external_texcoord_usage,
> >                              unsigned external_color_usage,
> > @@ -499,7 +499,7 @@ public:
> >     }
> >  
> >  private:
> > -   struct gl_shader *shader;
> > +   struct gl_linked_shader *shader;
> >     const varying_info_visitor *info;
> >     ir_variable *new_fragdata[MAX_DRAW_BUFFERS];
> >     ir_variable *new_texcoord[MAX_TEXTURE_COORD_UNITS];
> > @@ -511,7 +511,7 @@ private:
> >  } /* anonymous namespace */
> >  
> >  static void
> > -lower_texcoord_array(struct gl_shader *shader, const
> > varying_info_visitor *info)
> > +lower_texcoord_array(struct gl_linked_shader *shader, const
> > varying_info_visitor *info)
> >  {
> >     replace_varyings_visitor(shader, info,
> >                              (1 << MAX_TEXTURE_COORD_UNITS) - 1,
> > @@ -519,7 +519,7 @@ lower_texcoord_array(struct gl_shader *shader,
> > const varying_info_visitor *info)
> >  }
> >  
> >  static void
> > -lower_fragdata_array(struct gl_shader *shader)
> > +lower_fragdata_array(struct gl_linked_shader *shader)
> >  {
> >     varying_info_visitor info(ir_var_shader_out, true);
> >     info.get(shader->ir, 0, NULL);
> > @@ -530,7 +530,8 @@ lower_fragdata_array(struct gl_shader *shader)
> >  
> >  void
> >  do_dead_builtin_varyings(struct gl_context *ctx,
> > -                         gl_shader *producer, gl_shader *consumer,
> > +                         gl_linked_shader *producer,
> > +                         gl_linked_shader *consumer,
> >                           unsigned num_tfeedback_decls,
> >                           tfeedback_decl *tfeedback_decls)
> >  {
> > diff --git a/src/compiler/glsl/standalone.cpp
> > b/src/compiler/glsl/standalone.cpp
> > index d0057df..760fe8f 100644
> > --- a/src/compiler/glsl/standalone.cpp
> > +++ b/src/compiler/glsl/standalone.cpp
> > @@ -222,7 +222,7 @@ initialize_context(struct gl_context *ctx,
> > gl_api api)
> >     ctx->Const.GenerateTemporaryNames = true;
> >     ctx->Const.MaxPatchVertices = 32;
> >  
> > -   ctx->Driver.NewShader = _mesa_new_shader;
> > +   ctx->Driver.NewShader = _mesa_new_linked_shader;
> >  }
> >  
> >  /* Returned string will have 'ctx' as its ralloc owner. */
> > @@ -412,7 +412,7 @@ standalone_compile_shader(const struct
> > standalone_options *_options,
> >        }
> >  
> >        for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
> > -         struct gl_shader *shader = whole_program-
> > >_LinkedShaders[i];
> > +         struct gl_linked_shader *shader = whole_program-
> > >_LinkedShaders[i];
> >  
> >           if (!shader)
> >              continue;
> > diff --git a/src/compiler/glsl/standalone_scaffolding.cpp
> > b/src/compiler/glsl/standalone_scaffolding.cpp
> > index 396965a..b5dc523 100644
> > --- a/src/compiler/glsl/standalone_scaffolding.cpp
> > +++ b/src/compiler/glsl/standalone_scaffolding.cpp
> > @@ -84,6 +84,19 @@ _mesa_new_shader(struct gl_context *ctx, GLuint
> > name, gl_shader_stage stage)
> >     return shader;
> >  }
> >  
> > +struct gl_linked_shader *
> > +_mesa_new_linked_shader(gl_shader_stage stage)
> > +{
> > +   struct gl_linked_shader *shader;
> > +
> > +   assert(stage == MESA_SHADER_FRAGMENT || stage ==
> > MESA_SHADER_VERTEX);
> > +   shader = rzalloc(NULL, struct gl_linked_shader);
> > +   if (shader) {
> > +      shader->Stage = stage;
> > +   }
> > +   return shader;
> > +}
> > +
> >  void
> >  _mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh)
> >  {
> > @@ -93,6 +106,13 @@ _mesa_delete_shader(struct gl_context *ctx,
> > struct gl_shader *sh)
> >  }
> >  
> >  void
> > +_mesa_delete_linked_shader(struct gl_context *ctx,
> > +                           struct gl_linked_shader *sh)
> > +{
> > +   ralloc_free(sh);
> > +}
> > +
> > +void
> >  _mesa_clear_shader_program_data(struct gl_shader_program *shProg)
> >  {
> >     shProg->NumUniformStorage = 0;
> > diff --git a/src/compiler/glsl/standalone_scaffolding.h
> > b/src/compiler/glsl/standalone_scaffolding.h
> > index 15dc702..c6666c9 100644
> > --- a/src/compiler/glsl/standalone_scaffolding.h
> > +++ b/src/compiler/glsl/standalone_scaffolding.h
> > @@ -44,10 +44,17 @@ _mesa_reference_shader(struct gl_context *ctx,
> > struct gl_shader **ptr,
> >  extern "C" struct gl_shader *
> >  _mesa_new_shader(struct gl_context *ctx, GLuint name,
> > gl_shader_stage stage);
> >  
> > +extern "C" struct gl_linked_shader *
> > +_mesa_new_linked_shader(gl_shader_stage stage);
> > +
> >  extern "C" void
> >  _mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh);
> >  
> >  extern "C" void
> > +_mesa_delete_linked_shader(struct gl_context *ctx,
> > +                           struct gl_linked_shader *sh);
> > +
> > +extern "C" void
> >  _mesa_clear_shader_program_data(struct gl_shader_program *);
> >  
> >  extern "C" void
> > diff --git a/src/compiler/glsl/test_optpass.cpp
> > b/src/compiler/glsl/test_optpass.cpp
> > index fed1fab..f19d7e6 100644
> > --- a/src/compiler/glsl/test_optpass.cpp
> > +++ b/src/compiler/glsl/test_optpass.cpp
> > @@ -200,7 +200,7 @@ int test_optpass(int argc, char **argv)
> >     struct gl_context *ctx = &local_ctx;
> >     initialize_context_to_defaults(ctx, API_OPENGL_COMPAT);
> >  
> > -   ctx->Driver.NewShader = _mesa_new_shader;
> > +   ctx->Driver.NewShader = _mesa_new_linked_shader;
> >     ir_variable::temporaries_allocate_names = true;
> >  
> >     struct gl_shader *shader = rzalloc(NULL, struct gl_shader);
> > diff --git a/src/mesa/drivers/common/meta.c
> > b/src/mesa/drivers/common/meta.c
> > index be671b4..df57c87 100644
> > --- a/src/mesa/drivers/common/meta.c
> > +++ b/src/mesa/drivers/common/meta.c
> > @@ -129,7 +129,7 @@ meta_compile_shader_with_debug(struct
> > gl_context *ctx, gl_shader_stage stage,
> >     const GLuint name = ~0;
> >     struct gl_shader *sh;
> >  
> > -   sh = ctx->Driver.NewShader(ctx, name, stage);
> > +   sh = _mesa_new_shader(ctx, name, stage);
> >     sh->Source = strdup(source);
> >     sh->CompileStatus = false;
> >     _mesa_compile_shader(ctx, sh);
> > diff --git a/src/mesa/drivers/dri/i965/brw_context.c
> > b/src/mesa/drivers/dri/i965/brw_context.c
> > index c7a66cb..5e3c9d1 100644
> > --- a/src/mesa/drivers/dri/i965/brw_context.c
> > +++ b/src/mesa/drivers/dri/i965/brw_context.c
> > @@ -239,8 +239,9 @@ intel_update_state(struct gl_context * ctx,
> > GLuint new_state)
> >  
> >     /* Resolve color for each active shader image. */
> >     for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
> > -      const struct gl_shader *shader = ctx->_Shader-
> > >CurrentProgram[i] ?
> > -         ctx->_Shader->CurrentProgram[i]->_LinkedShaders[i] :
> > NULL;
> > +      const struct gl_linked_shader *shader =
> > +         ctx->_Shader->CurrentProgram[i] ?
> > +            ctx->_Shader->CurrentProgram[i]->_LinkedShaders[i] :
> > NULL;
> >  
> >        if (unlikely(shader && shader->NumImages)) {
> >           for (unsigned j = 0; j < shader->NumImages; j++) {
> > diff --git a/src/mesa/drivers/dri/i965/brw_context.h
> > b/src/mesa/drivers/dri/i965/brw_context.h
> > index 9d7a5b4..cc03278 100644
> > --- a/src/mesa/drivers/dri/i965/brw_context.h
> > +++ b/src/mesa/drivers/dri/i965/brw_context.h
> > @@ -366,7 +366,7 @@ struct brw_compute_program {
> >  
> > 
> >  struct brw_shader {
> > -   struct gl_shader base;
> > +   struct gl_linked_shader base;
> >  
> >     bool compiled_once;
> >  };
> > @@ -1581,15 +1581,15 @@ brw_update_sol_surface(struct brw_context
> > *brw,
> >                         uint32_t *out_offset, unsigned
> > num_vector_components,
> >                         unsigned stride_dwords, unsigned
> > offset_dwords);
> >  void brw_upload_ubo_surfaces(struct brw_context *brw,
> > -			     struct gl_shader *shader,
> > +			     struct gl_linked_shader *shader,
> >                               struct brw_stage_state *stage_state,
> >                               struct brw_stage_prog_data
> > *prog_data);
> >  void brw_upload_abo_surfaces(struct brw_context *brw,
> > -                             struct gl_shader *shader,
> > +                             struct gl_linked_shader *shader,
> >                               struct brw_stage_state *stage_state,
> >                               struct brw_stage_prog_data
> > *prog_data);
> >  void brw_upload_image_surfaces(struct brw_context *brw,
> > -                               struct gl_shader *shader,
> > +                               struct gl_linked_shader *shader,
> >                                 struct brw_stage_state
> > *stage_state,
> >                                 struct brw_stage_prog_data
> > *prog_data);
> >  
> > diff --git a/src/mesa/drivers/dri/i965/brw_gs.c
> > b/src/mesa/drivers/dri/i965/brw_gs.c
> > index 4ac1009..1ce74d8 100644
> > --- a/src/mesa/drivers/dri/i965/brw_gs.c
> > +++ b/src/mesa/drivers/dri/i965/brw_gs.c
> > @@ -98,7 +98,6 @@ brw_codegen_gs_prog(struct brw_context *brw,
> >                      struct brw_gs_prog_key *key)
> >  {
> >     struct brw_compiler *compiler = brw->intelScreen->compiler;
> > -   struct gl_shader *shader = prog-
> > >_LinkedShaders[MESA_SHADER_GEOMETRY];
> >     struct brw_stage_state *stage_state = &brw->gs.base;
> >     struct brw_gs_prog_data prog_data;
> >     bool start_busy = false;
> > @@ -117,7 +116,7 @@ brw_codegen_gs_prog(struct brw_context *brw,
> >      * padding around uniform values below vec4 size, so the worst
> > case is that
> >      * every uniform is a float which gets padded to the size of a
> > vec4.
> >      */
> > -   struct gl_shader *gs = prog-
> > >_LinkedShaders[MESA_SHADER_GEOMETRY];
> > +   struct gl_linked_shader *gs = prog-
> > >_LinkedShaders[MESA_SHADER_GEOMETRY];
> >     struct brw_shader *bgs = (struct brw_shader *) gs;
> >     int param_count = gp->program.Base.nir->num_uniforms / 4;
> >  
> > @@ -161,7 +160,7 @@ brw_codegen_gs_prog(struct brw_context *brw,
> >     char *error_str;
> >     const unsigned *program =
> >        brw_compile_gs(brw->intelScreen->compiler, brw, mem_ctx,
> > key,
> > -                     &prog_data, shader->Program->nir, prog,
> > +                     &prog_data, gs->Program->nir, prog,
> >                       st_index, &program_size, &error_str);
> >     if (program == NULL) {
> >        ralloc_free(mem_ctx);
> > diff --git a/src/mesa/drivers/dri/i965/brw_link.cpp
> > b/src/mesa/drivers/dri/i965/brw_link.cpp
> > index 76c580b..5374685 100644
> > --- a/src/mesa/drivers/dri/i965/brw_link.cpp
> > +++ b/src/mesa/drivers/dri/i965/brw_link.cpp
> > @@ -43,12 +43,12 @@ static bool
> >  brw_shader_precompile(struct gl_context *ctx,
> >                        struct gl_shader_program *sh_prog)
> >  {
> > -   struct gl_shader *vs = sh_prog-
> > >_LinkedShaders[MESA_SHADER_VERTEX];
> > -   struct gl_shader *tcs = sh_prog-
> > >_LinkedShaders[MESA_SHADER_TESS_CTRL];
> > -   struct gl_shader *tes = sh_prog-
> > >_LinkedShaders[MESA_SHADER_TESS_EVAL];
> > -   struct gl_shader *gs = sh_prog-
> > >_LinkedShaders[MESA_SHADER_GEOMETRY];
> > -   struct gl_shader *fs = sh_prog-
> > >_LinkedShaders[MESA_SHADER_FRAGMENT];
> > -   struct gl_shader *cs = sh_prog-
> > >_LinkedShaders[MESA_SHADER_COMPUTE];
> > +   struct gl_linked_shader *vs = sh_prog-
> > >_LinkedShaders[MESA_SHADER_VERTEX];
> > +   struct gl_linked_shader *tcs = sh_prog-
> > >_LinkedShaders[MESA_SHADER_TESS_CTRL];
> > +   struct gl_linked_shader *tes = sh_prog-
> > >_LinkedShaders[MESA_SHADER_TESS_EVAL];
> > +   struct gl_linked_shader *gs = sh_prog-
> > >_LinkedShaders[MESA_SHADER_GEOMETRY];
> > +   struct gl_linked_shader *fs = sh_prog-
> > >_LinkedShaders[MESA_SHADER_FRAGMENT];
> > +   struct gl_linked_shader *cs = sh_prog-
> > >_LinkedShaders[MESA_SHADER_COMPUTE];
> >  
> >     if (fs && !brw_fs_precompile(ctx, sh_prog, fs->Program))
> >        return false;
> > @@ -89,7 +89,7 @@ static void
> >  process_glsl_ir(gl_shader_stage stage,
> >                  struct brw_context *brw,
> >                  struct gl_shader_program *shader_prog,
> > -                struct gl_shader *shader)
> > +                struct gl_linked_shader *shader)
> >  {
> >     struct gl_context *ctx = &brw->ctx;
> >     const struct brw_compiler *compiler = brw->intelScreen-
> > >compiler;
> > @@ -186,16 +186,14 @@ process_glsl_ir(gl_shader_stage stage,
> >     }
> >  }
> >  
> > -extern "C" struct gl_shader *
> > -brw_new_shader(struct gl_context *ctx, GLuint name,
> > gl_shader_stage stage)
> > +extern "C" struct gl_linked_shader *
> > +brw_new_shader(gl_shader_stage stage)
> >  {
> >     struct brw_shader *shader;
> >  
> >     shader = rzalloc(NULL, struct brw_shader);
> >     if (shader) {
> >        shader->base.Stage = stage;
> > -      shader->base.Name = name;
> > -      _mesa_init_shader(ctx, &shader->base);
> >     }
> >  
> >     return &shader->base;
> > @@ -209,13 +207,13 @@ brw_link_shader(struct gl_context *ctx,
> > struct gl_shader_program *shProg)
> >     unsigned int stage;
> >  
> >     for (stage = 0; stage < ARRAY_SIZE(shProg->_LinkedShaders);
> > stage++) {
> > -      struct gl_shader *shader = shProg->_LinkedShaders[stage];
> > +      struct gl_linked_shader *shader = shProg-
> > >_LinkedShaders[stage];
> >        if (!shader)
> >           continue;
> >  
> >        struct gl_program *prog =
> >           ctx->Driver.NewProgram(ctx,
> > _mesa_shader_stage_to_program(stage),
> > -                                shader->Name);
> > +                                0);
> >        if (!prog)
> >          return false;
> >        prog->Parameters = _mesa_new_parameter_list();
> > diff --git a/src/mesa/drivers/dri/i965/brw_program.c
> > b/src/mesa/drivers/dri/i965/brw_program.c
> > index a1a8116..aee9467 100644
> > --- a/src/mesa/drivers/dri/i965/brw_program.c
> > +++ b/src/mesa/drivers/dri/i965/brw_program.c
> > @@ -651,7 +651,7 @@ brw_stage_prog_data_free(const void *p)
> >  
> >  void
> >  brw_dump_ir(const char *stage, struct gl_shader_program
> > *shader_prog,
> > -            struct gl_shader *shader, struct gl_program *prog)
> > +            struct gl_linked_shader *shader, struct gl_program
> > *prog)
> >  {
> >     if (shader_prog) {
> >        if (shader->ir) {
> > diff --git a/src/mesa/drivers/dri/i965/brw_program.h
> > b/src/mesa/drivers/dri/i965/brw_program.h
> > index 4d6299f..5874d93 100644
> > --- a/src/mesa/drivers/dri/i965/brw_program.h
> > +++ b/src/mesa/drivers/dri/i965/brw_program.h
> > @@ -60,7 +60,7 @@ brw_stage_prog_data_free(const void *prog_data);
> >  
> >  void
> >  brw_dump_ir(const char *stage, struct gl_shader_program
> > *shader_prog,
> > -            struct gl_shader *shader, struct gl_program *prog);
> > +            struct gl_linked_shader *shader, struct gl_program
> > *prog);
> >  
> >  void brw_upload_tcs_prog(struct brw_context *brw,
> >                           uint64_t per_vertex_slots, uint32_t
> > per_patch_slots);
> > diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp
> > b/src/mesa/drivers/dri/i965/brw_shader.cpp
> > index 5ce7b82..f3b5487 100644
> > --- a/src/mesa/drivers/dri/i965/brw_shader.cpp
> > +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
> > @@ -1158,7 +1158,7 @@
> > brw_assign_common_binding_table_offsets(gl_shader_stage stage,
> >                                          struct brw_stage_prog_data
> > *stage_prog_data,
> >                                          uint32_t
> > next_binding_table_offset)
> >  {
> > -   const struct gl_shader *shader = NULL;
> > +   const struct gl_linked_shader *shader = NULL;
> >     int num_textures = _mesa_fls(prog->SamplersUsed);
> >  
> >     if (shader_prog)
> > @@ -1320,7 +1320,7 @@ brw_compile_tes(const struct brw_compiler
> > *compiler,
> >                  char **error_str)
> >  {
> >     const struct brw_device_info *devinfo = compiler->devinfo;
> > -   struct gl_shader *shader =
> > +   struct gl_linked_shader *shader =
> >        shader_prog->_LinkedShaders[MESA_SHADER_TESS_EVAL];
> >     const bool is_scalar = compiler-
> > >scalar_stage[MESA_SHADER_TESS_EVAL];
> >  
> > diff --git a/src/mesa/drivers/dri/i965/brw_shader.h
> > b/src/mesa/drivers/dri/i965/brw_shader.h
> > index d74c6d6..dd9eb2d 100644
> > --- a/src/mesa/drivers/dri/i965/brw_shader.h
> > +++ b/src/mesa/drivers/dri/i965/brw_shader.h
> > @@ -289,8 +289,7 @@ bool brw_cs_precompile(struct gl_context *ctx,
> >                         struct gl_program *prog);
> >  
> >  GLboolean brw_link_shader(struct gl_context *ctx, struct
> > gl_shader_program *prog);
> > -struct gl_shader *brw_new_shader(struct gl_context *ctx, GLuint
> > name,
> > -                                 gl_shader_stage stage);
> > +struct gl_linked_shader *brw_new_shader(gl_shader_stage stage);
> >  
> >  int type_size_scalar(const struct glsl_type *type);
> >  int type_size_vec4(const struct glsl_type *type);
> > diff --git a/src/mesa/drivers/dri/i965/brw_tcs.c
> > b/src/mesa/drivers/dri/i965/brw_tcs.c
> > index d488715..3ba9f2c 100644
> > --- a/src/mesa/drivers/dri/i965/brw_tcs.c
> > +++ b/src/mesa/drivers/dri/i965/brw_tcs.c
> > @@ -197,7 +197,7 @@ brw_codegen_tcs_prog(struct brw_context *brw,
> >      * padding around uniform values below vec4 size, so the worst
> > case is that
> >      * every uniform is a float which gets padded to the size of a
> > vec4.
> >      */
> > -   struct gl_shader *tcs = shader_prog ?
> > +   struct gl_linked_shader *tcs = shader_prog ?
> >        shader_prog->_LinkedShaders[MESA_SHADER_TESS_CTRL] : NULL;
> >     int param_count = nir->num_uniforms / 4;
> >  
> > diff --git a/src/mesa/drivers/dri/i965/brw_tes.c
> > b/src/mesa/drivers/dri/i965/brw_tes.c
> > index d7b3e69..001655d 100644
> > --- a/src/mesa/drivers/dri/i965/brw_tes.c
> > +++ b/src/mesa/drivers/dri/i965/brw_tes.c
> > @@ -150,7 +150,8 @@ brw_codegen_tes_prog(struct brw_context *brw,
> >      * padding around uniform values below vec4 size, so the worst
> > case is that
> >      * every uniform is a float which gets padded to the size of a
> > vec4.
> >      */
> > -   struct gl_shader *tes = shader_prog-
> > >_LinkedShaders[MESA_SHADER_TESS_EVAL];
> > +   struct gl_linked_shader *tes =
> > +      shader_prog->_LinkedShaders[MESA_SHADER_TESS_EVAL];
> >     int param_count = nir->num_uniforms / 4;
> >  
> >     prog_data.base.base.param =
> > 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 eed16ac..c101e05 100644
> > --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
> > +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
> > @@ -946,7 +946,7 @@ const struct brw_tracked_state
> > brw_cs_texture_surfaces = {
> >  
> >  void
> >  brw_upload_ubo_surfaces(struct brw_context *brw,
> > -			struct gl_shader *shader,
> > +			struct gl_linked_shader *shader,
> >                          struct brw_stage_state *stage_state,
> >                          struct brw_stage_prog_data *prog_data)
> >  {
> > @@ -1064,7 +1064,7 @@ const struct brw_tracked_state
> > brw_cs_ubo_surfaces = {
> >  
> >  void
> >  brw_upload_abo_surfaces(struct brw_context *brw,
> > -                        struct gl_shader *shader,
> > +                        struct gl_linked_shader *shader,
> >                          struct brw_stage_state *stage_state,
> >                          struct brw_stage_prog_data *prog_data)
> >  {
> > @@ -1350,7 +1350,7 @@ update_image_surface(struct brw_context *brw,
> >  
> >  void
> >  brw_upload_image_surfaces(struct brw_context *brw,
> > -                          struct gl_shader *shader,
> > +                          struct gl_linked_shader *shader,
> >                            struct brw_stage_state *stage_state,
> >                            struct brw_stage_prog_data *prog_data)
> >  {
> > diff --git a/src/mesa/main/api_validate.c
> > b/src/mesa/main/api_validate.c
> > index 8efbf50..c096224 100644
> > --- a/src/mesa/main/api_validate.c
> > +++ b/src/mesa/main/api_validate.c
> > @@ -207,7 +207,8 @@ _mesa_valid_prim_mode(struct gl_context *ctx,
> > GLenum mode, const char *name)
> >        GLenum mode_before_gs = mode;
> >  
> >        if (tes) {
> > -         struct gl_shader *tes_sh = tes-
> > >_LinkedShaders[MESA_SHADER_TESS_EVAL];
> > +         struct gl_linked_shader *tes_sh =
> > +            tes->_LinkedShaders[MESA_SHADER_TESS_EVAL];
> >           if (tes_sh->TessEval.PointMode)
> >              mode_before_gs = GL_POINTS;
> >           else if (tes_sh->TessEval.PrimitiveMode == GL_ISOLINES)
> > @@ -324,7 +325,8 @@ _mesa_valid_prim_mode(struct gl_context *ctx,
> > GLenum mode, const char *name)
> >        else if (ctx->_Shader-
> > >CurrentProgram[MESA_SHADER_TESS_EVAL]) {
> >           struct gl_shader_program *tes =
> >              ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL];
> > -         struct gl_shader *tes_sh = tes-
> > >_LinkedShaders[MESA_SHADER_TESS_EVAL];
> > +         struct gl_linked_shader *tes_sh =
> > +            tes->_LinkedShaders[MESA_SHADER_TESS_EVAL];
> >           if (tes_sh->TessEval.PointMode)
> >              pass = ctx->TransformFeedback.Mode == GL_POINTS;
> >           else if (tes_sh->TessEval.PrimitiveMode == GL_ISOLINES)
> > diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
> > index f918bb6..4891e2a 100644
> > --- a/src/mesa/main/dd.h
> > +++ b/src/mesa/main/dd.h
> > @@ -783,8 +783,7 @@ struct dd_function_table {
> >      * \name GLSL-related functions (ARB extensions and OpenGL 2.x)
> >      */
> >     /*@{*/
> > -   struct gl_shader *(*NewShader)(struct gl_context *ctx,
> > -                                  GLuint name, gl_shader_stage
> > stage);
> > +   struct gl_linked_shader *(*NewShader)(gl_shader_stage stage);
> >     void (*UseProgram)(struct gl_context *ctx, struct
> > gl_shader_program *shProg);
> >     /*@}*/
> >  
> > diff --git a/src/mesa/main/ff_fragment_shader.cpp
> > b/src/mesa/main/ff_fragment_shader.cpp
> > index d0def7c..f90d31a 100644
> > --- a/src/mesa/main/ff_fragment_shader.cpp
> > +++ b/src/mesa/main/ff_fragment_shader.cpp
> > @@ -1203,7 +1203,7 @@ create_new_program(struct gl_context *ctx,
> > struct state_key *key)
> >     _mesa_glsl_parse_state *state;
> >  
> >     p.mem_ctx = ralloc_context(NULL);
> > -   p.shader = ctx->Driver.NewShader(ctx, 0, MESA_SHADER_FRAGMENT);
> > +   p.shader = _mesa_new_shader(ctx, 0, MESA_SHADER_FRAGMENT);
> >     p.shader->ir = new(p.shader) exec_list;
> >     state = new(p.shader) _mesa_glsl_parse_state(ctx,
> > MESA_SHADER_FRAGMENT,
> >  						p.shader);
> > diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
> > index 73ae55d..fdd445f 100644
> > --- a/src/mesa/main/mtypes.h
> > +++ b/src/mesa/main/mtypes.h
> > @@ -2235,30 +2235,13 @@ struct gl_subroutine_function
> >  };
> >  
> >  /**
> > - * A GLSL vertex or fragment shader object.
> > + * A linked GLSL shader object.
> >   */
> > -struct gl_shader
> > +struct gl_linked_shader
> >  {
> > -   /** GL_FRAGMENT_SHADER || GL_VERTEX_SHADER ||
> > GL_GEOMETRY_SHADER_ARB ||
> > -    *  GL_TESS_CONTROL_SHADER || GL_TESS_EVALUATION_SHADER.
> > -    * Must be the first field.
> > -    */
> > -   GLenum Type;
> >     gl_shader_stage Stage;
> > -   GLuint Name;  /**< AKA the handle */
> > -   GLint RefCount;  /**< Reference count */
> > -   GLchar *Label;   /**< GL_KHR_debug */
> > -   GLboolean DeletePending;
> > -   GLboolean CompileStatus;
> > -   bool IsES;              /**< True if this shader uses GLSL ES
> > */
> > -
> > -   GLuint SourceChecksum;       /**< for debug/logging purposes */
> > -   const GLchar *Source;  /**< Source code string */
> >  
> >     struct gl_program *Program;  /**< Post-compile assembly code */
> > -   GLchar *InfoLog;
> > -
> > -   unsigned Version;       /**< GLSL version used for linking */
> >  
> >     /**
> >      * \name Sampler tracking
> > @@ -2450,6 +2433,126 @@ struct gl_shader
> >     struct gl_subroutine_function *SubroutineFunctions;
> >  };
> >  
> > +/**
> > + * A GLSL shader object.
> > + */
> > +struct gl_shader
> > +{
> > +   /** GL_FRAGMENT_SHADER || GL_VERTEX_SHADER ||
> > GL_GEOMETRY_SHADER_ARB ||
> > +    *  GL_TESS_CONTROL_SHADER || GL_TESS_EVALUATION_SHADER.
> > +    * Must be the first field.
> > +    */
> > +   GLenum Type;
> > +   gl_shader_stage Stage;
> > +   GLuint Name;  /**< AKA the handle */
> > +   GLint RefCount;  /**< Reference count */
> > +   GLchar *Label;   /**< GL_KHR_debug */
> > +   GLboolean DeletePending;
> > +   GLboolean CompileStatus;
> > +   bool IsES;              /**< True if this shader uses GLSL ES
> > */
> > +
> > +   GLuint SourceChecksum;       /**< for debug/logging purposes */
> > +   const GLchar *Source;  /**< Source code string */
> > +
> > +   GLchar *InfoLog;
> > +
> > +   unsigned Version;       /**< GLSL version used for linking */
> > +
> > +   struct exec_list *ir;
> > +   struct glsl_symbol_table *symbols;
> > +
> > +   bool uses_builtin_functions;
> > +   bool uses_gl_fragcoord;
> > +   bool redeclares_gl_fragcoord;
> > +   bool ARB_fragment_coord_conventions_enable;
> > +
> > +   /**
> > +    * Fragment shader state from GLSL 1.50 layout qualifiers.
> > +    */
> > +   bool origin_upper_left;
> > +   bool pixel_center_integer;
> > +
> > +   struct {
> > +      /** Global xfb_stride out qualifier if any */
> > +      GLuint BufferStride[MAX_FEEDBACK_BUFFERS];
> > +   } TransformFeedback;
> > +
> > +   /**
> > +    * Tessellation Control shader state from layout qualifiers.
> > +    */
> > +   struct {
> > +      /**
> > +       * 0 - vertices not declared in shader, or
> > +       * 1 .. GL_MAX_PATCH_VERTICES
> > +       */
> > +      GLint VerticesOut;
> > +   } TessCtrl;
> > +
> > +   /**
> > +    * Tessellation Evaluation shader state from layout qualifiers.
> > +    */
> > +   struct {
> > +      /**
> > +       * GL_TRIANGLES, GL_QUADS, GL_ISOLINES or PRIM_UNKNOWN if
> > it's not set
> > +       * in this shader.
> > +       */
> > +      GLenum PrimitiveMode;
> > +      /**
> > +       * GL_EQUAL, GL_FRACTIONAL_ODD, GL_FRACTIONAL_EVEN, or 0 if
> > it's not set
> > +       * in this shader.
> > +       */
> > +      GLenum Spacing;
> > +      /**
> > +       * GL_CW, GL_CCW, or 0 if it's not set in this shader.
> > +       */
> > +      GLenum VertexOrder;
> > +      /**
> > +       * 1, 0, or -1 if it's not set in this shader.
> > +       */
> > +      int PointMode;
> > +   } TessEval;
> > +
> > +   /**
> > +    * Geometry shader state from GLSL 1.50 layout qualifiers.
> > +    */
> > +   struct {
> > +      GLint VerticesOut;
> > +      /**
> > +       * 0 - Invocations count not declared in shader, or
> > +       * 1 .. MAX_GEOMETRY_SHADER_INVOCATIONS
> > +       */
> > +      GLint Invocations;
> > +      /**
> > +       * GL_POINTS, GL_LINES, GL_LINES_ADJACENCY, GL_TRIANGLES, or
> > +       * GL_TRIANGLES_ADJACENCY, or PRIM_UNKNOWN if it's not set
> > in this
> > +       * shader.
> > +       */
> > +      GLenum InputType;
> > +       /**
> > +        * GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP, or
> > PRIM_UNKNOWN if
> > +        * it's not set in this shader.
> > +        */
> > +      GLenum OutputType;
> > +   } Geom;
> > +
> > +   /**
> > +    * Whether early fragment tests are enabled as defined by
> > +    * ARB_shader_image_load_store.
> > +    */
> > +   bool EarlyFragmentTests;
> > +
> > +   /**
> > +    * Compute shader state from ARB_compute_shader layout
> > qualifiers.
> > +    */
> > +   struct {
> > +      /**
> > +       * Size specified using local_size_{x,y,z}, or all 0's to
> > indicate that
> > +       * it's not set in this shader.
> > +       */
> > +      unsigned LocalSize[3];
> > +   } Comp;
> > +};
> > +
> >  
> >  struct gl_uniform_buffer_variable
> >  {
> > @@ -2834,7 +2937,7 @@ struct gl_shader_program
> >      * \c MESA_SHADER_* defines.  Entries for non-existent stages
> > will be
> >      * \c NULL.
> >      */
> > -   struct gl_shader *_LinkedShaders[MESA_SHADER_STAGES];
> > +   struct gl_linked_shader *_LinkedShaders[MESA_SHADER_STAGES];
> >  
> >     /** List of all active resources after linking. */
> >     struct gl_program_resource *ProgramResourceList;
> > diff --git a/src/mesa/main/shader_query.cpp
> > b/src/mesa/main/shader_query.cpp
> > index 5956ce4..b5e1a44 100644
> > --- a/src/mesa/main/shader_query.cpp
> > +++ b/src/mesa/main/shader_query.cpp
> > @@ -1264,7 +1264,7 @@ _mesa_program_resource_prop(struct
> > gl_shader_program *shProg,
> >        return 1;
> >     case GL_COMPATIBLE_SUBROUTINES: {
> >        const struct gl_uniform_storage *uni;
> > -      struct gl_shader *sh;
> > +      struct gl_linked_shader *sh;
> >        unsigned count, i;
> >        int j;
> >  
> > diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
> > index 142e750..962b42e 100644
> > --- a/src/mesa/main/shaderapi.c
> > +++ b/src/mesa/main/shaderapi.c
> > @@ -2175,7 +2175,8 @@
> > _mesa_copy_linked_program_data(gl_shader_stage type,
> >     case MESA_SHADER_TESS_EVAL: {
> >        struct gl_tess_eval_program *dst_tep =
> >           (struct gl_tess_eval_program *) dst;
> > -      struct gl_shader *tes_sh = src-
> > >_LinkedShaders[MESA_SHADER_TESS_EVAL];
> > +      struct gl_linked_shader *tes_sh =
> > +         src->_LinkedShaders[MESA_SHADER_TESS_EVAL];
> >  
> >        dst_tep->PrimitiveMode = tes_sh->TessEval.PrimitiveMode;
> >        dst_tep->Spacing = tes_sh->TessEval.Spacing;
> > @@ -2187,7 +2188,8 @@
> > _mesa_copy_linked_program_data(gl_shader_stage type,
> >     }
> >     case MESA_SHADER_GEOMETRY: {
> >        struct gl_geometry_program *dst_gp = (struct
> > gl_geometry_program *) dst;
> > -      struct gl_shader *geom_sh = src-
> > >_LinkedShaders[MESA_SHADER_GEOMETRY];
> > +      struct gl_linked_shader *geom_sh =
> > +         src->_LinkedShaders[MESA_SHADER_GEOMETRY];
> >  
> >        dst_gp->VerticesIn = src->Geom.VerticesIn;
> >        dst_gp->VerticesOut = geom_sh->Geom.VerticesOut;
> > @@ -2420,7 +2422,7 @@ _mesa_GetActiveSubroutineUniformiv(GLuint
> > program, GLenum shadertype,
> >     GET_CURRENT_CONTEXT(ctx);
> >     const char *api_name = "glGetActiveSubroutineUniformiv";
> >     struct gl_shader_program *shProg;
> > -   struct gl_shader *sh;
> > +   struct gl_linked_shader *sh;
> >     gl_shader_stage stage;
> >     struct gl_program_resource *res;
> >     const struct gl_uniform_storage *uni;
> > @@ -2585,7 +2587,7 @@ _mesa_UniformSubroutinesuiv(GLenum
> > shadertype, GLsizei count,
> >     GET_CURRENT_CONTEXT(ctx);
> >     const char *api_name = "glUniformSubroutinesuiv";
> >     struct gl_shader_program *shProg;
> > -   struct gl_shader *sh;
> > +   struct gl_linked_shader *sh;
> >     gl_shader_stage stage;
> >     int i;
> >  
> > @@ -2683,7 +2685,7 @@ _mesa_GetUniformSubroutineuiv(GLenum
> > shadertype, GLint location,
> >     GET_CURRENT_CONTEXT(ctx);
> >     const char *api_name = "glGetUniformSubroutineuiv";
> >     struct gl_shader_program *shProg;
> > -   struct gl_shader *sh;
> > +   struct gl_linked_shader *sh;
> >     gl_shader_stage stage;
> >  
> >     if (!_mesa_has_shader_subroutine(ctx)) {
> > @@ -2730,7 +2732,7 @@ _mesa_GetProgramStageiv(GLuint program,
> > GLenum shadertype,
> >     GET_CURRENT_CONTEXT(ctx);
> >     const char *api_name = "glGetProgramStageiv";
> >     struct gl_shader_program *shProg;
> > -   struct gl_shader *sh;
> > +   struct gl_linked_shader *sh;
> >     gl_shader_stage stage;
> >  
> >     if (!_mesa_has_shader_subroutine(ctx)) {
> > @@ -2812,7 +2814,8 @@ _mesa_GetProgramStageiv(GLuint program,
> > GLenum shadertype,
> >  }
> >  
> >  static int
> > -find_compat_subroutine(struct gl_shader *sh, const struct
> > glsl_type *type)
> > +find_compat_subroutine(struct gl_linked_shader *sh,
> > +                       const struct glsl_type *type)
> >  {
> >     int i, j;
> >  
> > @@ -2827,7 +2830,7 @@ find_compat_subroutine(struct gl_shader *sh,
> > const struct glsl_type *type)
> >  }
> >  
> >  static void
> > -_mesa_shader_init_subroutine_defaults(struct gl_shader *sh)
> > +_mesa_shader_init_subroutine_defaults(struct gl_linked_shader *sh)
> >  {
> >     int i, j;
> >  
> > diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c
> > index f3d5c2e..93fdc66 100644
> > --- a/src/mesa/main/shaderobj.c
> > +++ b/src/mesa/main/shaderobj.c
> > @@ -99,7 +99,6 @@ _mesa_init_shader(struct gl_context *ctx, struct
> > gl_shader *shader)
> >  
> >  /**
> >   * Allocate a new gl_shader object, initialize it.
> > - * Called via ctx->Driver.NewShader()
> >   */
> >  struct gl_shader *
> >  _mesa_new_shader(struct gl_context *ctx, GLuint name,
> > gl_shader_stage stage)
> > @@ -116,6 +115,22 @@ _mesa_new_shader(struct gl_context *ctx,
> > GLuint name, gl_shader_stage stage)
> >  
> > 
> >  /**
> > + * Allocate a new gl_linked_shader object.
> > + * Called via ctx->Driver.NewShader()
> > + */
> > +struct gl_linked_shader *
> > +_mesa_new_linked_shader(gl_shader_stage stage)
> > +{
> > +   struct gl_linked_shader *shader;
> > +   shader = rzalloc(NULL, struct gl_linked_shader);
> > +   if (shader) {
> > +      shader->Stage = stage;
> > +   }
> > +   return shader;
> > +}
> > +
> > +
> > +/**
> >   * Delete a shader object.
> >   */
> >  void
> > @@ -123,6 +138,17 @@ _mesa_delete_shader(struct gl_context *ctx,
> > struct gl_shader *sh)
> >  {
> >     free((void *)sh->Source);
> >     free(sh->Label);
> > +   ralloc_free(sh);
> > +}
> > +
> > +
> > +/**
> > + * Delete a shader object.
> > + */
> > +void
> > +_mesa_delete_linked_shader(struct gl_context *ctx,
> > +                           struct gl_linked_shader *sh)
> > +{
> >     _mesa_reference_program(ctx, &sh->Program, NULL);
> >     ralloc_free(sh);
> >  }
> > @@ -360,7 +386,7 @@ _mesa_free_shader_program_data(struct
> > gl_context *ctx,
> >  
> >     for (sh = 0; sh < MESA_SHADER_STAGES; sh++) {
> >        if (shProg->_LinkedShaders[sh] != NULL) {
> > -	 _mesa_delete_shader(ctx, shProg->_LinkedShaders[sh]);
> > +	 _mesa_delete_linked_shader(ctx, shProg-
> > >_LinkedShaders[sh]);
> >  	 shProg->_LinkedShaders[sh] = NULL;
> >        }
> >     }
> > @@ -436,6 +462,6 @@ _mesa_lookup_shader_program_err(struct
> > gl_context *ctx, GLuint name,
> >  void
> >  _mesa_init_shader_object_functions(struct dd_function_table
> > *driver)
> >  {
> > -   driver->NewShader = _mesa_new_shader;
> > +   driver->NewShader = _mesa_new_linked_shader;
> >     driver->LinkShader = _mesa_ir_link_shader;
> >  }
> > diff --git a/src/mesa/main/shaderobj.h b/src/mesa/main/shaderobj.h
> > index 3abd597..f331db1 100644
> > --- a/src/mesa/main/shaderobj.h
> > +++ b/src/mesa/main/shaderobj.h
> > @@ -82,9 +82,16 @@ _mesa_init_shader(struct gl_context *ctx, struct
> > gl_shader *shader);
> >  extern struct gl_shader *
> >  _mesa_new_shader(struct gl_context *ctx, GLuint name,
> > gl_shader_stage type);
> >  
> > +extern struct gl_linked_shader *
> > +_mesa_new_linked_shader(gl_shader_stage type);
> > +
> >  extern void
> >  _mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh);
> >  
> > +extern void
> > +_mesa_delete_linked_shader(struct gl_context *ctx,
> > +                           struct gl_linked_shader *sh);
> > +
> >  extern struct gl_shader_program *
> >  _mesa_lookup_shader_program(struct gl_context *ctx, GLuint name);
> >  
> > diff --git a/src/mesa/main/uniform_query.cpp
> > b/src/mesa/main/uniform_query.cpp
> > index 127f097..67375a1 100644
> > --- a/src/mesa/main/uniform_query.cpp
> > +++ b/src/mesa/main/uniform_query.cpp
> > @@ -824,7 +824,7 @@ _mesa_uniform(struct gl_context *ctx, struct
> > gl_shader_program *shProg,
> >     if (uni->type->is_sampler()) {
> >        bool flushed = false;
> >        for (int i = 0; i < MESA_SHADER_STAGES; i++) {
> > -	 struct gl_shader *const sh = shProg->_LinkedShaders[i];
> > +	 struct gl_linked_shader *const sh = shProg-
> > >_LinkedShaders[i];
> >  
> >  	 /* If the shader stage doesn't use the sampler uniform,
> > skip this.
> >  	  */
> > @@ -876,7 +876,7 @@ _mesa_uniform(struct gl_context *ctx, struct
> > gl_shader_program *shProg,
> >     if (uni->type->is_image()) {
> >        for (int i = 0; i < MESA_SHADER_STAGES; i++) {
> >  	 if (uni->opaque[i].active) {
> > -            struct gl_shader *sh = shProg->_LinkedShaders[i];
> > +            struct gl_linked_shader *sh = shProg-
> > >_LinkedShaders[i];
> >  
> >              for (int j = 0; j < count; j++)
> >                 sh->ImageUnits[uni->opaque[i].index + offset + j] =
> > diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c
> > index d02f92e..3921644 100644
> > --- a/src/mesa/main/uniforms.c
> > +++ b/src/mesa/main/uniforms.c
> > @@ -68,7 +68,7 @@ _mesa_update_shader_textures_used(struct
> > gl_shader_program *shProg,
> >  				  struct gl_program *prog)
> >  {
> >     GLbitfield mask = prog->SamplersUsed;
> > -   struct gl_shader *shader =
> > +   struct gl_linked_shader *shader =
> >        shProg-
> > >_LinkedShaders[_mesa_program_enum_to_shader_stage(prog->Target)];
> >  
> >     assert(shader);
> > diff --git a/src/mesa/program/ir_to_mesa.cpp
> > b/src/mesa/program/ir_to_mesa.cpp
> > index cf47c0d..e74d94f 100644
> > --- a/src/mesa/program/ir_to_mesa.cpp
> > +++ b/src/mesa/program/ir_to_mesa.cpp
> > @@ -2469,7 +2469,7 @@ add_uniform_to_shader::visit_field(const
> > glsl_type *type, const char *name,
> >  void
> >  _mesa_generate_parameters_list_for_uniforms(struct
> > gl_shader_program
> >  					    *shader_program,
> > -					    struct gl_shader *sh,
> > +					    struct
> > gl_linked_shader *sh,
> >  					    struct
> > gl_program_parameter_list
> >  					    *params)
> >  {
> > @@ -2779,7 +2779,7 @@ ir_to_mesa_visitor::copy_propagate(void)
> >  static struct gl_program *
> >  get_mesa_program(struct gl_context *ctx,
> >                   struct gl_shader_program *shader_program,
> > -		 struct gl_shader *shader)
> > +		 struct gl_linked_shader *shader)
> >  {
> >     ir_to_mesa_visitor v;
> >     struct prog_instruction *mesa_instructions, *mesa_inst;
> > diff --git a/src/mesa/program/ir_to_mesa.h
> > b/src/mesa/program/ir_to_mesa.h
> > index a70f575..be45ba0 100644
> > --- a/src/mesa/program/ir_to_mesa.h
> > +++ b/src/mesa/program/ir_to_mesa.h
> > @@ -39,7 +39,7 @@ GLboolean _mesa_ir_link_shader(struct gl_context
> > *ctx, struct gl_shader_program
> >  void
> >  _mesa_generate_parameters_list_for_uniforms(struct
> > gl_shader_program
> >  					    *shader_program,
> > -					    struct gl_shader *sh,
> > +					    struct
> > gl_linked_shader *sh,
> >  					    struct
> > gl_program_parameter_list
> >  					    *params);
> >  void
> > diff --git a/src/mesa/program/prog_print.c
> > b/src/mesa/program/prog_print.c
> > index 755d644..b8d7cca 100644
> > --- a/src/mesa/program/prog_print.c
> > +++ b/src/mesa/program/prog_print.c
> > @@ -994,16 +994,6 @@ _mesa_write_shader_to_file(const struct
> > gl_shader *shader)
> >     if (shader->InfoLog) {
> >        fputs(shader->InfoLog, f);
> >     }
> > -   if (shader->CompileStatus && shader->Program) {
> > -      fprintf(f, "/* GPU code */\n");
> > -      fprintf(f, "/*\n");
> > -      _mesa_fprint_program_opt(f, shader->Program,
> > PROG_PRINT_DEBUG, GL_TRUE);
> > -      fprintf(f, "*/\n");
> > -      fprintf(f, "/* Parameters / constants */\n");
> > -      fprintf(f, "/*\n");
> > -      _mesa_fprint_parameter_list(f, shader->Program->Parameters);
> > -      fprintf(f, "*/\n");
> > -   }
> >  
> >     fclose(f);
> >  }
> > @@ -1015,7 +1005,7 @@ _mesa_write_shader_to_file(const struct
> > gl_shader *shader)
> >   * _mesa_write_shader_to_file function.
> >   */
> >  void
> > -_mesa_append_uniforms_to_file(const struct gl_shader *shader)
> > +_mesa_append_uniforms_to_file(const struct gl_linked_shader
> > *shader)
> >  {
> >     const struct gl_program *const prog = shader->Program;
> >     const char *type;
> > @@ -1027,7 +1017,7 @@ _mesa_append_uniforms_to_file(const struct
> > gl_shader *shader)
> >     else
> >        type = "vert";
> >  
> > -   _mesa_snprintf(filename, sizeof(filename), "shader_%u.%s",
> > shader->Name, type);
> > +   _mesa_snprintf(filename, sizeof(filename), "shader.%s", type);
> >     f = fopen(filename, "a"); /* append */
> >     if (!f) {
> >        fprintf(stderr, "Unable to open %s for appending\n",
> > filename);
> > diff --git a/src/mesa/program/prog_print.h
> > b/src/mesa/program/prog_print.h
> > index 9058dfa..7b1e1fe 100644
> > --- a/src/mesa/program/prog_print.h
> > +++ b/src/mesa/program/prog_print.h
> > @@ -118,7 +118,7 @@ extern void
> >  _mesa_write_shader_to_file(const struct gl_shader *shader);
> >  
> >  extern void
> > -_mesa_append_uniforms_to_file(const struct gl_shader *shader);
> > +_mesa_append_uniforms_to_file(const struct gl_linked_shader
> > *shader);
> >  
> > 
> >  #ifdef __cplusplus
> > diff --git a/src/mesa/state_tracker/st_atom_constbuf.c
> > b/src/mesa/state_tracker/st_atom_constbuf.c
> > index a980dbe..594db1e 100644
> > --- a/src/mesa/state_tracker/st_atom_constbuf.c
> > +++ b/src/mesa/state_tracker/st_atom_constbuf.c
> > @@ -265,7 +265,7 @@ const struct st_tracked_state
> > st_update_cs_constants = {
> >  };
> >  
> >  static void st_bind_ubos(struct st_context *st,
> > -                           struct gl_shader *shader,
> > +                           struct gl_linked_shader *shader,
> >                             unsigned shader_type)
> >  {
> >     unsigned i;
> > diff --git a/src/mesa/state_tracker/st_atom_image.c
> > b/src/mesa/state_tracker/st_atom_image.c
> > index f8a0044..bc9344e 100644
> > --- a/src/mesa/state_tracker/st_atom_image.c
> > +++ b/src/mesa/state_tracker/st_atom_image.c
> > @@ -45,7 +45,7 @@
> >  #include "st_format.h"
> >  
> >  static void
> > -st_bind_images(struct st_context *st, struct gl_shader *shader,
> > +st_bind_images(struct st_context *st, struct gl_linked_shader
> > *shader,
> >                unsigned shader_type)
> >  {
> >     unsigned i;
> > diff --git a/src/mesa/state_tracker/st_atom_storagebuf.c
> > b/src/mesa/state_tracker/st_atom_storagebuf.c
> > index 37b4c4d..0f96e6d 100644
> > --- a/src/mesa/state_tracker/st_atom_storagebuf.c
> > +++ b/src/mesa/state_tracker/st_atom_storagebuf.c
> > @@ -41,7 +41,7 @@
> >  #include "st_program.h"
> >  
> >  static void
> > -st_bind_ssbos(struct st_context *st, struct gl_shader *shader,
> > +st_bind_ssbos(struct st_context *st, struct gl_linked_shader
> > *shader,
> >                unsigned shader_type)
> >  {
> >     unsigned i;
> > diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp
> > b/src/mesa/state_tracker/st_glsl_to_nir.cpp
> > index a880564..52470a0 100644
> > --- a/src/mesa/state_tracker/st_glsl_to_nir.cpp
> > +++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp
> > @@ -347,7 +347,7 @@ st_finalize_nir(struct st_context *st, struct
> > gl_program *prog, nir_shader *nir)
> >  struct gl_program *
> >  st_nir_get_mesa_program(struct gl_context *ctx,
> >                          struct gl_shader_program *shader_program,
> > -                        struct gl_shader *shader)
> > +                        struct gl_linked_shader *shader)
> >  {
> >     struct gl_program *prog;
> >     GLenum target = _mesa_shader_stage_to_program(shader->Stage);
> > diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> > b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> > index 07ec91a..9315153 100644
> > --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> > +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> > @@ -376,7 +376,7 @@ public:
> >     struct gl_context *ctx;
> >     struct gl_program *prog;
> >     struct gl_shader_program *shader_program;
> > -   struct gl_shader *shader;
> > +   struct gl_linked_shader *shader;
> >     struct gl_shader_compiler_options *options;
> >  
> >     int next_temp;
> > @@ -6452,7 +6452,7 @@ out:
> >  static struct gl_program *
> >  get_mesa_program_tgsi(struct gl_context *ctx,
> >                        struct gl_shader_program *shader_program,
> > -                      struct gl_shader *shader)
> > +                      struct gl_linked_shader *shader)
> >  {
> >     glsl_to_tgsi_visitor* v;
> >     struct gl_program *prog;
> > @@ -6663,7 +6663,7 @@ get_mesa_program_tgsi(struct gl_context *ctx,
> >  static struct gl_program *
> >  get_mesa_program(struct gl_context *ctx,
> >                   struct gl_shader_program *shader_program,
> > -                 struct gl_shader *shader)
> > +                 struct gl_linked_shader *shader)
> >  {
> >     struct pipe_screen *pscreen = ctx->st->pipe->screen;
> >     unsigned ptarget = st_shader_stage_to_ptarget(shader->Stage);
> > diff --git a/src/mesa/state_tracker/st_nir.h
> > b/src/mesa/state_tracker/st_nir.h
> > index 49ba573..19e2d2d 100644
> > --- a/src/mesa/state_tracker/st_nir.h
> > +++ b/src/mesa/state_tracker/st_nir.h
> > @@ -43,7 +43,7 @@ void st_finalize_nir(struct st_context *st,
> > struct gl_program *prog, nir_shader
> >  struct gl_program *
> >  st_nir_get_mesa_program(struct gl_context *ctx,
> >                          struct gl_shader_program *shader_program,
> > -                        struct gl_shader *shader);
> > +                        struct gl_linked_shader *shader);
> >  
> >  #ifdef __cplusplus
> >  }
> > diff --git a/src/mesa/state_tracker/st_program.c
> > b/src/mesa/state_tracker/st_program.c
> > index f2b5537..57b0935 100644
> > --- a/src/mesa/state_tracker/st_program.c
> > +++ b/src/mesa/state_tracker/st_program.c
> > @@ -1756,10 +1756,6 @@ destroy_shader_program_variants_cb(GLuint
> > key, void *data, void *userData)
> >           struct gl_shader_program *shProg = (struct
> > gl_shader_program *) data;
> >           GLuint i;
> >  
> > -         for (i = 0; i < shProg->NumShaders; i++) {
> > -            destroy_program_variants(st, shProg->Shaders[i]-
> > >Program);
> > -         }
> > -
> >  	 for (i = 0; i < ARRAY_SIZE(shProg->_LinkedShaders); i++)
> > {
> >  	    if (shProg->_LinkedShaders[i])
> >                 destroy_program_variants(st, shProg-
> > >_LinkedShaders[i]->Program);
> > @@ -1772,9 +1768,6 @@ destroy_shader_program_variants_cb(GLuint
> > key, void *data, void *userData)
> >     case GL_TESS_CONTROL_SHADER:
> >     case GL_TESS_EVALUATION_SHADER:
> >     case GL_COMPUTE_SHADER:
> > -      {
> > -         destroy_program_variants(st, shader->Program);
> > -      }
> >        break;
> >     default:
> >        assert(0);
> 
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list