[Mesa-dev] [PATCH 2/2] st/mesa: add support for gl_ClipDistance

Brian Paul brianp at vmware.com
Mon Dec 19 07:05:52 PST 2011


On 12/17/2011 03:15 PM, Bryan Cain wrote:
> ---
>   src/mesa/state_tracker/st_glsl_to_tgsi.cpp |   49 +++++++++++++++++++++++++---
>   src/mesa/state_tracker/st_program.c        |   18 ++++++++++
>   2 files changed, 62 insertions(+), 5 deletions(-)
>
> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> index b929806..3e8df78 100644
> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> @@ -304,6 +304,7 @@ public:
>      int samplers_used;
>      bool indirect_addr_temps;
>      bool indirect_addr_consts;
> +   int num_clip_distances;
>
>      int glsl_version;
>      bool native_integers;
> @@ -4618,9 +4619,16 @@ st_translate_program(
>         }
>
>         for (i = 0; i<  numOutputs; i++) {
> -         t->outputs[i] = ureg_DECL_output(ureg,
> -                                          outputSemanticName[i],
> -                                          outputSemanticIndex[i]);
> +         if (outputSemanticName[i] == TGSI_SEMANTIC_CLIPDIST) {
> +            int mask = ((1<<  (program->num_clip_distances - 4*outputSemanticIndex[i])) - 1)&  0xf;

Being nit-picky, but 0xf should be replaced by TGSI_WRITEMASK_XYZW to 
be totally clear.


> +            t->outputs[i] = ureg_DECL_output_masked(ureg,
> +                                                    outputSemanticName[i],
> +                                                    outputSemanticIndex[i],
> +                                                    mask);
> +         } else
> +            t->outputs[i] = ureg_DECL_output(ureg,
> +                                             outputSemanticName[i],
> +                                             outputSemanticIndex[i]);

I'd like to see { } braces around the else clause.


>            if ((outputSemanticName[i] == TGSI_SEMANTIC_PSIZE)&&  proginfo->Id) {
>               /* Writing to the point size result register requires special
>                * handling to implement clamping.
> @@ -4797,7 +4805,8 @@ out:
>   static struct gl_program *
>   get_mesa_program(struct gl_context *ctx,
>                    struct gl_shader_program *shader_program,
> -        	 struct gl_shader *shader)
> +                 struct gl_shader *shader,
> +                 int num_clip_distances)
>   {
>      glsl_to_tgsi_visitor* v = new glsl_to_tgsi_visitor();
>      struct gl_program *prog;
> @@ -4842,6 +4851,7 @@ get_mesa_program(struct gl_context *ctx,
>      v->options = options;
>      v->glsl_version = ctx->Const.GLSLVersion;
>      v->native_integers = ctx->Const.NativeIntegers;
> +   v->num_clip_distances = num_clip_distances;
>
>      _mesa_generate_parameters_list_for_uniforms(shader_program, shader,
>   					       prog->Parameters);
> @@ -4971,6 +4981,27 @@ get_mesa_program(struct gl_context *ctx,
>      return prog;
>   }
>
> +/**
> + * Searches through the IR for a declaration of gl_ClipDistance and returns the
> + * declared size of the gl_ClipDistance array.  Returns 0 if gl_ClipDistance is
> + * not declared in the IR.
> + */
> +int get_clip_distance_size(exec_list *ir)
> +{
> +   foreach_iter (exec_list_iterator, iter, *ir) {
> +      ir_instruction *inst = (ir_instruction *)iter.get();
> +      ir_variable *var = inst->as_variable();
> +      if (var == NULL) continue;
> +      if (!strcmp(var->name, "gl_ClipDistance"))
> +      {

The { should go on the same line as the 'if' like elsewhere.


> +         fprintf(stderr, "gl_ClipDistance found with size %i\n", var->type->length);

Left-over debug code?


> +         return var->type->length;
> +      }
> +   }
> +
> +   return 0;
> +}
> +
>   extern "C" {
>
>   struct gl_shader *
> @@ -5009,6 +5040,7 @@ st_new_shader_program(struct gl_context *ctx, GLuint name)
>   GLboolean
>   st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
>   {
> +   int num_clip_distances[MESA_SHADER_TYPES];
>      assert(prog->LinkStatus);
>
>      for (unsigned i = 0; i<  MESA_SHADER_TYPES; i++) {
> @@ -5020,6 +5052,11 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
>         const struct gl_shader_compiler_options *options =
>               &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(prog->_LinkedShaders[i]->Type)];
>
> +      /* We have to determine the length of the gl_ClipDistance array before
> +       * the array is lowered to two vec4s by lower_clip_distance().
> +       */
> +      num_clip_distances[i] = get_clip_distance_size(ir);
> +
>         do {
>            progress = false;
>
> @@ -5036,6 +5073,7 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
>   	   || progress;
>
>            progress = lower_quadop_vector(ir, false) || progress;
> +         progress = lower_clip_distance(ir) || progress;
>
>            if (options->MaxIfDepth == 0)
>               progress = lower_discard(ir) || progress;
> @@ -5070,7 +5108,8 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
>         if (prog->_LinkedShaders[i] == NULL)
>            continue;
>
> -      linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]);
> +      linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i],
> +                                     num_clip_distances[i]);
>
>         if (linked_prog) {
>   	 static const GLenum targets[] = {
> diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
> index b83c561..b404503 100644
> --- a/src/mesa/state_tracker/st_program.c
> +++ b/src/mesa/state_tracker/st_program.c
> @@ -244,6 +244,14 @@ st_prepare_vertex_program(struct gl_context *ctx,
>               stvp->output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
>               stvp->output_semantic_index[slot] = 0;
>               break;
> +         case VERT_RESULT_CLIP_DIST0:
> +            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST;
> +            stvp->output_semantic_index[slot] = 0;
> +            break;
> +         case VERT_RESULT_CLIP_DIST1:
> +            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST;
> +            stvp->output_semantic_index[slot] = 1;
> +            break;
>            case VERT_RESULT_EDGE:
>               assert(0);
>               break;
> @@ -547,6 +555,16 @@ st_translate_fragment_program(struct st_context *st,
>                  input_semantic_index[slot] = 0;
>                  interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
>                  break;
> +            case FRAG_ATTRIB_CLIP_DIST0:
> +               input_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST;
> +               input_semantic_index[slot] = 0;
> +               interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
> +               break;
> +            case FRAG_ATTRIB_CLIP_DIST1:
> +               input_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST;
> +               input_semantic_index[slot] = 1;
> +               interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
> +               break;
>                  /* In most cases, there is nothing special about these
>                   * inputs, so adopt a convention to use the generic
>                   * semantic name and the mesa FRAG_ATTRIB_ number as the



More information about the mesa-dev mailing list