[Mesa-dev] [PATCH 1/7] draw/tgsi: implement geom shader invocation support.

Roland Scheidegger sroland at vmware.com
Wed May 27 04:42:14 PDT 2015


Am 27.05.2015 um 09:45 schrieb Dave Airlie:
> From: Dave Airlie <airlied at redhat.com>
> 
> This is just for softpipe, llvmpipe won't work without
> some changes.
> 
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
>  src/gallium/auxiliary/draw/draw_gs.c   | 47 +++++++++++++++++++++-------------
>  src/gallium/auxiliary/draw/draw_gs.h   |  2 ++
>  src/gallium/auxiliary/tgsi/tgsi_scan.c |  2 ++
>  src/gallium/auxiliary/tgsi/tgsi_scan.h |  1 +
>  4 files changed, 34 insertions(+), 18 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c
> index 6375d41..755e527 100644
> --- a/src/gallium/auxiliary/draw/draw_gs.c
> +++ b/src/gallium/auxiliary/draw/draw_gs.c
> @@ -190,9 +190,15 @@ static void tgsi_gs_prepare(struct draw_geometry_shader *shader,
>                              const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS])
>  {
>     struct tgsi_exec_machine *machine = shader->machine;
> -
> +   int j;
>     tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS,
>                                    constants, constants_size);
> +
> +   if (shader->info.uses_invocationid) {
> +      unsigned i = machine->SysSemanticToIndex[TGSI_SEMANTIC_INVOCATIONID];
> +      for (j = 0; j < TGSI_QUAD_SIZE; j++)
> +         machine->SystemValue[i].i[j] = shader->invocation_id;
> +   }
>  }
>  
>  static unsigned tgsi_gs_run(struct draw_geometry_shader *shader,
> @@ -555,7 +561,7 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
>      * overflown vertices into some area where they won't harm anyone */
>     unsigned total_verts_per_buffer = shader->primitive_boundary *
>        num_in_primitives;
> -
> +   unsigned invocation;
>     //Assume at least one primitive
>     max_out_prims = MAX2(max_out_prims, 1);
>  
> @@ -564,7 +570,7 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
>     output_verts->stride = output_verts->vertex_size;
>     output_verts->verts =
>        (struct vertex_header *)MALLOC(output_verts->vertex_size *
> -                                     total_verts_per_buffer);
> +                                     total_verts_per_buffer * shader->num_invocations);
This can't get very large, right?

Otherwise,

Reviewed-by: Roland Scheidegger <sroland at vmware.com>


>     debug_assert(output_verts->verts);
>  
>  #if 0
> @@ -592,7 +598,7 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
>     shader->input = input;
>     shader->input_info = input_info;
>     FREE(shader->primitive_lengths);
> -   shader->primitive_lengths = MALLOC(max_out_prims * sizeof(unsigned));
> +   shader->primitive_lengths = MALLOC(max_out_prims * sizeof(unsigned) * shader->num_invocations);
>  
>  
>  #ifdef HAVE_LLVM
> @@ -622,23 +628,26 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
>     }
>  #endif
>  
> -   shader->prepare(shader, constants, constants_size);
> +   for (invocation = 0; invocation < shader->num_invocations; invocation++) {
> +      shader->invocation_id = invocation;
>  
> -   if (input_prim->linear)
> -      gs_run(shader, input_prim, input_verts,
> -             output_prims, output_verts);
> -   else
> -      gs_run_elts(shader, input_prim, input_verts,
> -                  output_prims, output_verts);
> +      shader->prepare(shader, constants, constants_size);
>  
> -   /* Flush the remaining primitives. Will happen if
> -    * num_input_primitives % 4 != 0
> -    */
> -   if (shader->fetched_prim_count > 0) {
> -      gs_flush(shader);
> -   }
> +      if (input_prim->linear)
> +         gs_run(shader, input_prim, input_verts,
> +                output_prims, output_verts);
> +      else
> +         gs_run_elts(shader, input_prim, input_verts,
> +                     output_prims, output_verts);
>  
> -   debug_assert(shader->fetched_prim_count == 0);
> +      /* Flush the remaining primitives. Will happen if
> +       * num_input_primitives % 4 != 0
> +       */
> +      if (shader->fetched_prim_count > 0) {
> +         gs_flush(shader);
> +      }
> +      debug_assert(shader->fetched_prim_count == 0);
> +   }
>  
>     /* Update prim_info:
>      */
> @@ -771,6 +780,8 @@ draw_create_geometry_shader(struct draw_context *draw,
>           gs->info.properties[TGSI_PROPERTY_GS_OUTPUT_PRIM];
>     gs->max_output_vertices =
>           gs->info.properties[TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES];
> +   gs->num_invocations =
> +      gs->info.properties[TGSI_PROPERTY_GS_INVOCATIONS];
>     if (!gs->max_output_vertices)
>        gs->max_output_vertices = 32;
>  
> diff --git a/src/gallium/auxiliary/draw/draw_gs.h b/src/gallium/auxiliary/draw/draw_gs.h
> index 49e93d5..663ba84 100644
> --- a/src/gallium/auxiliary/draw/draw_gs.h
> +++ b/src/gallium/auxiliary/draw/draw_gs.h
> @@ -90,6 +90,8 @@ struct draw_geometry_shader {
>     unsigned vector_length;
>     unsigned max_out_prims;
>  
> +   unsigned num_invocations;
> +   unsigned invocation_id;
>  #ifdef HAVE_LLVM
>     struct draw_gs_inputs *gs_input;
>     struct draw_gs_jit_context *jit_context;
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c
> index d821072..e0506f4 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_scan.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c
> @@ -230,6 +230,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
>                    }
>                    else if (semName == TGSI_SEMANTIC_PRIMID) {
>                       info->uses_primid = TRUE;
> +                  } else if (semName == TGSI_SEMANTIC_INVOCATIONID) {
> +                     info->uses_invocationid = TRUE;
>                    }
>                 }
>                 else if (file == TGSI_FILE_OUTPUT) {
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.h b/src/gallium/auxiliary/tgsi/tgsi_scan.h
> index 0ea0e88..77c649a 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_scan.h
> +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.h
> @@ -85,6 +85,7 @@ struct tgsi_shader_info
>     boolean uses_basevertex;
>     boolean uses_primid;
>     boolean uses_frontface;
> +   boolean uses_invocationid;
>     boolean writes_psize;
>     boolean writes_clipvertex;
>     boolean writes_viewport_index;
> 



More information about the mesa-dev mailing list