[Mesa-dev] [PATCH 4/6] glsl: Make a little tracking class for emitting IR lists.

Kenneth Graunke kenneth at whitecape.org
Mon Apr 9 23:29:09 PDT 2012


On 04/09/2012 02:22 PM, Eric Anholt wrote:
> This lets us significantly shorten p->instructions->push_tail(ir), and
> will be used in a few more places.
> ---
>   src/glsl/ir_builder.cpp              |    6 +++
>   src/glsl/ir_builder.h                |    8 ++++
>   src/mesa/main/ff_fragment_shader.cpp |   78 ++++++++++++----------------------
>   3 files changed, 42 insertions(+), 50 deletions(-)
>
> diff --git a/src/glsl/ir_builder.cpp b/src/glsl/ir_builder.cpp
> index 29cc9bc..98ac3c1 100644
> --- a/src/glsl/ir_builder.cpp
> +++ b/src/glsl/ir_builder.cpp
> @@ -28,6 +28,12 @@ using namespace ir_builder;
>
>   namespace ir_builder {
>
> +void
> +ir_factory::emit(ir_instruction *ir)
> +{
> +   instructions->push_tail(ir);
> +}
> +
>   ir_swizzle *
>   swizzle(operand a, int swizzle, int components)
>   {
> diff --git a/src/glsl/ir_builder.h b/src/glsl/ir_builder.h
> index d2c729a..350f9a3 100644
> --- a/src/glsl/ir_builder.h
> +++ b/src/glsl/ir_builder.h
> @@ -50,6 +50,14 @@ public:
>      ir_rvalue *val;
>   };
>
> +class ir_factory {
> +public:
> +   void emit(ir_instruction *ir);
> +
> +   exec_list *instructions;
> +   void *mem_ctx;
> +};
> +
>   ir_expression *expr(ir_expression_operation op, operand a, operand b);
>   ir_expression *add(operand a, operand b);
>   ir_expression *sub(operand a, operand b);
> diff --git a/src/mesa/main/ff_fragment_shader.cpp b/src/mesa/main/ff_fragment_shader.cpp
> index bc77ebd..555df42 100644
> --- a/src/mesa/main/ff_fragment_shader.cpp
> +++ b/src/mesa/main/ff_fragment_shader.cpp
> @@ -511,12 +511,11 @@ static GLuint make_state_key( struct gl_context *ctx,  struct state_key *key )
>
>   /** State used to build the fragment program:
>    */
> -struct texenv_fragment_program {
> +class texenv_fragment_program : public ir_factory {
> +public:
>      struct gl_shader_program *shader_program;
>      struct gl_shader *shader;
> -   exec_list *instructions;
>      exec_list *top_instructions;
> -   void *mem_ctx;
>      struct state_key *state;
>
>      ir_variable *src_texture[MAX_TEXTURE_COORD_UNITS];
> @@ -827,10 +826,9 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit)
>      ir_variable *temp_var = new(p->mem_ctx) ir_variable(glsl_type::vec4_type,
>   						       "texenv_combine",
>   						       ir_var_temporary);
> -   p->instructions->push_tail(temp_var);
> +   p->emit(temp_var);
>
>      ir_dereference *deref;
> -   ir_assignment *assign;
>      ir_rvalue *val;
>
>      /* Emit the RGB and A combine ops
> @@ -846,8 +844,7 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit)
>   	 val = saturate(val);
>
>         deref = new(p->mem_ctx) ir_dereference_variable(temp_var);
> -      assign = new(p->mem_ctx) ir_assignment(deref, val);
> -      p->instructions->push_tail(assign);
> +      p->emit(new(p->mem_ctx) ir_assignment(deref, val));
>      }
>      else if (key->unit[unit].ModeRGB == MODE_DOT3_RGBA_EXT ||
>   	    key->unit[unit].ModeRGB == MODE_DOT3_RGBA) {
> @@ -859,8 +856,7 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit)
>         if (rgb_saturate)
>   	 val = saturate(val);
>         deref = new(p->mem_ctx) ir_dereference_variable(temp_var);
> -      assign = new(p->mem_ctx) ir_assignment(deref, val);
> -      p->instructions->push_tail(assign);
> +      p->emit(new(p->mem_ctx) ir_assignment(deref, val));
>      }
>      else {
>         /* Need to do something to stop from re-emitting identical
> @@ -874,8 +870,7 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit)
>         if (rgb_saturate)
>   	 val = saturate(val);
>         deref = new(p->mem_ctx) ir_dereference_variable(temp_var);
> -      assign = new(p->mem_ctx) ir_assignment(deref, val, NULL, WRITEMASK_XYZ);
> -      p->instructions->push_tail(assign);
> +      p->emit(new(p->mem_ctx) ir_assignment(deref, val, NULL, WRITEMASK_XYZ));
>
>         val = emit_combine(p, unit,
>   			 key->unit[unit].NumArgsA,
> @@ -885,8 +880,7 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit)
>         if (alpha_saturate)
>   	 val = saturate(val);
>         deref = new(p->mem_ctx) ir_dereference_variable(temp_var);
> -      assign = new(p->mem_ctx) ir_assignment(deref, val, NULL, WRITEMASK_W);
> -      p->instructions->push_tail(assign);
> +      p->emit(new(p->mem_ctx) ir_assignment(deref, val, NULL, WRITEMASK_W));
>      }
>
>      deref = new(p->mem_ctx) ir_dereference_variable(temp_var);
> @@ -923,7 +917,6 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit)
>   static void load_texture( struct texenv_fragment_program *p, GLuint unit )
>   {
>      ir_dereference *deref;
> -   ir_assignment *assign;
>
>      if (p->src_texture[unit])
>         return;
> @@ -948,12 +941,11 @@ static void load_texture( struct texenv_fragment_program *p, GLuint unit )
>         p->src_texture[unit] = new(p->mem_ctx) ir_variable(glsl_type::vec4_type,
>   							 "dummy_tex",
>   							 ir_var_temporary);
> -      p->instructions->push_tail(p->src_texture[unit]);
> +      p->emit(p->src_texture[unit]);
>
>         deref = new(p->mem_ctx) ir_dereference_variable(p->src_texture[unit]);
> -      assign = new(p->mem_ctx) ir_assignment(deref,
> -					     new(p->mem_ctx) ir_constant(0.0f));
> -      p->instructions->push_tail(assign);
> +      p->emit(new(p->mem_ctx) ir_assignment(deref,
> +					    new(p->mem_ctx) ir_constant(0.0f)));
>         return ;
>      }
>
> @@ -1018,7 +1010,7 @@ static void load_texture( struct texenv_fragment_program *p, GLuint unit )
>      p->src_texture[unit] = new(p->mem_ctx) ir_variable(glsl_type::vec4_type,
>   						      "tex",
>   						      ir_var_temporary);
> -   p->instructions->push_tail(p->src_texture[unit]);
> +   p->emit(p->src_texture[unit]);
>
>      ir_texture *tex = new(p->mem_ctx) ir_texture(ir_tex);
>
> @@ -1045,8 +1037,7 @@ static void load_texture( struct texenv_fragment_program *p, GLuint unit )
>      tex->projector = swizzle_w(texcoord);
>
>      deref = new(p->mem_ctx) ir_dereference_variable(p->src_texture[unit]);
> -   assign = new(p->mem_ctx) ir_assignment(deref, tex);
> -   p->instructions->push_tail(assign);
> +   p->emit(new(p->mem_ctx) ir_assignment(deref, tex));
>   }
>
>   static void
> @@ -1125,7 +1116,6 @@ load_texunit_bumpmap( struct texenv_fragment_program *p, GLuint unit )
>       * note only 2 coords are affected the rest are left unchanged (mul by 0)
>       */
>      ir_dereference *deref;
> -   ir_assignment *assign;
>      ir_rvalue *bump_x, *bump_y;
>
>      texcoord = smear(p, texcoord);
> @@ -1134,11 +1124,10 @@ load_texunit_bumpmap( struct texenv_fragment_program *p, GLuint unit )
>      ir_variable *bumped = new(p->mem_ctx) ir_variable(texcoord->type,
>   						     "bump_texcoord",
>   						     ir_var_temporary);
> -   p->instructions->push_tail(bumped);
> +   p->emit(bumped);
>
>      deref = new(p->mem_ctx) ir_dereference_variable(bumped);
> -   assign = new(p->mem_ctx) ir_assignment(deref, texcoord);
> -   p->instructions->push_tail(assign);
> +   p->emit(new(p->mem_ctx) ir_assignment(deref, texcoord));
>
>      /* bump_texcoord.xy += arg0.x * rotmat0 + arg0.y * rotmat1 */
>      bump = get_source(p, key->unit[unit].OptRGB[0].Source, unit);
> @@ -1150,8 +1139,7 @@ load_texunit_bumpmap( struct texenv_fragment_program *p, GLuint unit )
>      expr = add(swizzle_xy(bumped), add(bump_x, bump_y));
>
>      deref = new(p->mem_ctx) ir_dereference_variable(bumped);
> -   assign = new(p->mem_ctx) ir_assignment(deref, expr, NULL, WRITEMASK_XY);
> -   p->instructions->push_tail(assign);
> +   p->emit(new(p->mem_ctx) ir_assignment(deref, expr, NULL, WRITEMASK_XY));
>
>      p->texcoord_tex[bumpedUnitNr] = bumped;
>   }
> @@ -1171,7 +1159,6 @@ emit_fog_instructions(struct texenv_fragment_program *p,
>      ir_rvalue *f, *temp;
>      ir_variable *params, *oparams;
>      ir_variable *fogcoord;
> -   ir_assignment *assign;
>
>      /* Temporary storage for the whole fog result.  Fog calculations
>       * only affect rgb so we're hanging on to the .a value of fragcolor
> @@ -1180,10 +1167,9 @@ emit_fog_instructions(struct texenv_fragment_program *p,
>      ir_variable *fog_result = new(p->mem_ctx) ir_variable(glsl_type::vec4_type,
>   							 "fog_result",
>   							 ir_var_auto);
> -   p->instructions->push_tail(fog_result);
> +   p->emit(fog_result);
>      temp = new(p->mem_ctx) ir_dereference_variable(fog_result);
> -   assign = new(p->mem_ctx) ir_assignment(temp, fragcolor);
> -   p->instructions->push_tail(assign);
> +   p->emit(new(p->mem_ctx) ir_assignment(temp, fragcolor));
>
>      fragcolor = swizzle_xyz(fog_result);
>
> @@ -1194,7 +1180,7 @@ emit_fog_instructions(struct texenv_fragment_program *p,
>
>      ir_variable *f_var = new(p->mem_ctx) ir_variable(glsl_type::float_type,
>   						    "fog_factor", ir_var_auto);
> -   p->instructions->push_tail(f_var);
> +   p->emit(f_var);
>
>      switch (key->fog_mode) {
>      case FOG_LINEAR:
> @@ -1226,13 +1212,12 @@ emit_fog_instructions(struct texenv_fragment_program *p,
>         ir_variable *temp_var = new(p->mem_ctx) ir_variable(glsl_type::float_type,
>   							  "fog_temp",
>   							  ir_var_auto);
> -      p->instructions->push_tail(temp_var);
> +      p->emit(temp_var);
>
>         f = mul(f, swizzle_w(oparams));
>
>         temp = new(p->mem_ctx) ir_dereference_variable(temp_var);
> -      ir_assignment *assign = new(p->mem_ctx) ir_assignment(temp, f);
> -      p->instructions->push_tail(assign);
> +      p->emit(new(p->mem_ctx) ir_assignment(temp, f));
>
>         f = mul(temp_var, temp_var);
>         f = new(p->mem_ctx) ir_expression(ir_unop_neg, f);
> @@ -1243,8 +1228,7 @@ emit_fog_instructions(struct texenv_fragment_program *p,
>      f = saturate(f);
>
>      temp = new(p->mem_ctx) ir_dereference_variable(f_var);
> -   assign = new(p->mem_ctx) ir_assignment(temp, f);
> -   p->instructions->push_tail(assign);
> +   p->emit(new(p->mem_ctx) ir_assignment(temp, f));
>
>      f = sub(new(p->mem_ctx) ir_constant(1.0f), f_var);
>      temp = new(p->mem_ctx) ir_dereference_variable(params);
> @@ -1254,8 +1238,7 @@ emit_fog_instructions(struct texenv_fragment_program *p,
>      f = add(temp, mul(fragcolor, f_var));
>
>      ir_dereference *deref = new(p->mem_ctx) ir_dereference_variable(fog_result);
> -   assign = new(p->mem_ctx) ir_assignment(deref, f, NULL, WRITEMASK_XYZ);
> -   p->instructions->push_tail(assign);
> +   p->emit(new(p->mem_ctx) ir_assignment(deref, f, NULL, WRITEMASK_XYZ));
>
>      return new(p->mem_ctx) ir_dereference_variable(fog_result);
>   }
> @@ -1295,7 +1278,6 @@ emit_instructions(struct texenv_fragment_program *p)
>
>      ir_rvalue *cf = get_source(p, SRC_PREVIOUS, 0);
>      ir_dereference_variable *deref;
> -   ir_assignment *assign;
>
>      if (key->separate_specular) {
>         ir_rvalue *tmp0;
> @@ -1303,11 +1285,10 @@ emit_instructions(struct texenv_fragment_program *p)
>   							    "specular_add",
>   							    ir_var_temporary);
>
> -      p->instructions->push_tail(spec_result);
> +      p->emit(spec_result);
>
>         deref = new(p->mem_ctx) ir_dereference_variable(spec_result);
> -      assign = new(p->mem_ctx) ir_assignment(deref, cf);
> -      p->instructions->push_tail(assign);
> +      p->emit(new(p->mem_ctx) ir_assignment(deref, cf));
>
>         ir_rvalue *secondary;
>         if (p->state->inputs_available&  FRAG_BIT_COL1) {
> @@ -1322,8 +1303,7 @@ emit_instructions(struct texenv_fragment_program *p)
>         tmp0 = add(swizzle_xyz(spec_result), secondary);
>
>         deref = new(p->mem_ctx) ir_dereference_variable(spec_result);
> -      assign = new(p->mem_ctx) ir_assignment(deref, tmp0, NULL, WRITEMASK_XYZ);
> -      p->instructions->push_tail(assign);
> +      p->emit(new(p->mem_ctx) ir_assignment(deref, tmp0, NULL, WRITEMASK_XYZ));
>
>         cf = new(p->mem_ctx) ir_dereference_variable(spec_result);
>      }
> @@ -1335,8 +1315,7 @@ emit_instructions(struct texenv_fragment_program *p)
>      ir_variable *frag_color = p->shader->symbols->get_variable("gl_FragColor");
>      assert(frag_color);
>      deref = new(p->mem_ctx) ir_dereference_variable(frag_color);
> -   assign = new(p->mem_ctx) ir_assignment(deref, cf);
> -   p->instructions->push_tail(assign);
> +   p->emit(new(p->mem_ctx) ir_assignment(deref, cf));
>   }
>
>   /**
> @@ -1346,11 +1325,10 @@ emit_instructions(struct texenv_fragment_program *p)
>   static struct gl_shader_program *
>   create_new_program(struct gl_context *ctx, struct state_key *key)
>   {
> -   struct texenv_fragment_program p;
> +   texenv_fragment_program p;
>      unsigned int unit;
>      _mesa_glsl_parse_state *state;
>
> -   memset(&p, 0, sizeof(p));

Clearly you can't continue doing this memset, but I'm also wary of just 
removing it.  Nothing depends on these fields being init'd to zero?

If they do, it's probably cleanest to add a constructor.  Some of this 
code could probably go there.

Assuming the memset was just for paranoia:
Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>

>      p.mem_ctx = ralloc_context(NULL);
>      p.shader = ctx->Driver.NewShader(ctx, 0, GL_FRAGMENT_SHADER);
>      p.shader->ir = new(p.shader) exec_list;
> @@ -1384,7 +1362,7 @@ create_new_program(struct gl_context *ctx, struct state_key *key)
>      p.src_previous = NULL;
>
>      ir_function *main_f = new(p.mem_ctx) ir_function("main");
> -   p.instructions->push_tail(main_f);
> +   p.emit(main_f);
>      state->symbols->add_function(main_f);
>
>      ir_function_signature *main_sig =



More information about the mesa-dev mailing list