[Mesa-dev] [PATCH 2/3] draw: Implement support for primitive id

Jose Fonseca jfonseca at vmware.com
Sat Mar 30 02:43:29 PDT 2013



----- Original Message -----
> We were largely ignoring primitive id.
> 
> Signed-off-by: Zack Rusin <zackr at vmware.com>
> ---
>  src/gallium/auxiliary/draw/draw_gs.c            |   20 +++++++++++++++-----
>  src/gallium/auxiliary/draw/draw_gs.h            |    1 +
>  src/gallium/auxiliary/draw/draw_llvm.c          |   15 +++++++++++++--
>  src/gallium/auxiliary/draw/draw_llvm.h          |    3 ++-
>  src/gallium/auxiliary/gallivm/lp_bld_tgsi.h     |    1 +
>  src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c |    5 +++++
>  src/gallium/auxiliary/tgsi/tgsi_scan.c          |    2 ++
>  src/gallium/auxiliary/tgsi/tgsi_scan.h          |    1 +
>  8 files changed, 40 insertions(+), 8 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/draw/draw_gs.c
> b/src/gallium/auxiliary/draw/draw_gs.c
> index 378d158..cc2f2fa 100644
> --- a/src/gallium/auxiliary/draw/draw_gs.c
> +++ b/src/gallium/auxiliary/draw/draw_gs.c
> @@ -237,10 +237,7 @@ llvm_fetch_gs_input(struct draw_geometry_shader *shader,
>           (const char *)input_ptr + (indices[i] * input_vertex_stride));
>        for (slot = 0, vs_slot = 0; slot < shader->info.num_inputs; ++slot) {
>           if (shader->info.input_semantic_name[slot] == TGSI_SEMANTIC_PRIMID)
>           {
> -            (*input_data)[i][slot][0][prim_idx] =
> (float)shader->in_prim_idx;
> -            (*input_data)[i][slot][1][prim_idx] =
> (float)shader->in_prim_idx;
> -            (*input_data)[i][slot][2][prim_idx] =
> (float)shader->in_prim_idx;
> -            (*input_data)[i][slot][3][prim_idx] =
> (float)shader->in_prim_idx;
> +            /* skip. we handle system values through gallivm */
>           } else {
>              vs_slot = draw_gs_get_input_index(
>                          shader->info.input_semantic_name[slot],
> @@ -343,7 +340,8 @@ llvm_gs_run(struct draw_geometry_shader *shader,
>        shader->jit_context, shader->gs_input->data,
>        (struct vertex_header*)input,
>        input_primitives,
> -      shader->draw->instance_id);
> +      shader->draw->instance_id,
> +      shader->llvm_prim_ids);
>  
>     return ret;
>  }
> @@ -381,6 +379,8 @@ static void gs_point(struct draw_geometry_shader *shader,
>  
>     shader->fetch_inputs(shader, indices, 1,
>                          shader->fetched_prim_count);
> +   shader->llvm_prim_ids[shader->fetched_prim_count] =
> +      shader->in_prim_idx;
>     ++shader->in_prim_idx;
>     ++shader->fetched_prim_count;
>  
> @@ -398,6 +398,8 @@ static void gs_line(struct draw_geometry_shader *shader,
>  
>     shader->fetch_inputs(shader, indices, 2,
>                          shader->fetched_prim_count);
> +   shader->llvm_prim_ids[shader->fetched_prim_count] =
> +      shader->in_prim_idx;
>     ++shader->in_prim_idx;
>     ++shader->fetched_prim_count;
>     
> @@ -417,6 +419,8 @@ static void gs_line_adj(struct draw_geometry_shader
> *shader,
>  
>     shader->fetch_inputs(shader, indices, 4,
>                          shader->fetched_prim_count);
> +   shader->llvm_prim_ids[shader->fetched_prim_count] =
> +      shader->in_prim_idx;
>     ++shader->in_prim_idx;
>     ++shader->fetched_prim_count;
>  
> @@ -435,6 +439,8 @@ static void gs_tri(struct draw_geometry_shader *shader,
>  
>     shader->fetch_inputs(shader, indices, 3,
>                          shader->fetched_prim_count);
> +   shader->llvm_prim_ids[shader->fetched_prim_count] =
> +      shader->in_prim_idx;
>     ++shader->in_prim_idx;
>     ++shader->fetched_prim_count;
>  
> @@ -457,6 +463,8 @@ static void gs_tri_adj(struct draw_geometry_shader
> *shader,
>  
>     shader->fetch_inputs(shader, indices, 6,
>                          shader->fetched_prim_count);
> +   shader->llvm_prim_ids[shader->fetched_prim_count] =
> +      shader->in_prim_idx;
>     ++shader->in_prim_idx;
>     ++shader->fetched_prim_count;
>  
> @@ -728,6 +736,7 @@ draw_create_geometry_shader(struct draw_context *draw,
>  
>        gs->llvm_emitted_primitives = align_malloc(vector_size, vector_size);
>        gs->llvm_emitted_vertices = align_malloc(vector_size, vector_size);
> +      gs->llvm_prim_ids = align_malloc(vector_size, vector_size);
>  
>        gs->fetch_outputs = llvm_fetch_gs_outputs;
>        gs->fetch_inputs = llvm_fetch_gs_input;
> @@ -796,6 +805,7 @@ void draw_delete_geometry_shader(struct draw_context
> *draw,
>        }
>        align_free(dgs->llvm_emitted_primitives);
>        align_free(dgs->llvm_emitted_vertices);
> +      align_free(dgs->llvm_prim_ids);
>  
>        align_free(dgs->gs_input);
>     }
> diff --git a/src/gallium/auxiliary/draw/draw_gs.h
> b/src/gallium/auxiliary/draw/draw_gs.h
> index 9c82648..7c84139 100644
> --- a/src/gallium/auxiliary/draw/draw_gs.h
> +++ b/src/gallium/auxiliary/draw/draw_gs.h
> @@ -95,6 +95,7 @@ struct draw_geometry_shader {
>     int **llvm_prim_lengths;
>     int *llvm_emitted_primitives;
>     int *llvm_emitted_vertices;
> +   int *llvm_prim_ids;
>  #endif
>  
>     void (*fetch_inputs)(struct draw_geometry_shader *shader,
> diff --git a/src/gallium/auxiliary/draw/draw_llvm.c
> b/src/gallium/auxiliary/draw/draw_llvm.c
> index 4731c8c..d0199bb 100644
> --- a/src/gallium/auxiliary/draw/draw_llvm.c
> +++ b/src/gallium/auxiliary/draw/draw_llvm.c
> @@ -1891,10 +1891,11 @@ draw_gs_llvm_generate(struct draw_llvm *llvm,
>     struct gallivm_state *gallivm = variant->gallivm;
>     LLVMContextRef context = gallivm->context;
>     LLVMTypeRef int32_type = LLVMInt32TypeInContext(context);
> -   LLVMTypeRef arg_types[5];
> +   LLVMTypeRef arg_types[6];
>     LLVMTypeRef func_type;
>     LLVMValueRef variant_func;
>     LLVMValueRef context_ptr;
> +   LLVMValueRef prim_id_ptr;
>     LLVMBasicBlockRef block;
>     LLVMBuilderRef builder;
>     LLVMValueRef io_ptr, input_array, num_prims, mask_val;
> @@ -1908,6 +1909,8 @@ draw_gs_llvm_generate(struct draw_llvm *llvm,
>     LLVMValueRef consts_ptr;
>     LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][TGSI_NUM_CHANNELS];
>     struct lp_build_mask_context mask;
> +   const struct tgsi_shader_info *gs_info = &variant->shader->base.info;
> +   unsigned vector_length = variant->shader->base.vector_length;
>  
>     memset(&system_values, 0, sizeof(system_values));
>  
> @@ -1918,6 +1921,8 @@ draw_gs_llvm_generate(struct draw_llvm *llvm,
>     arg_types[2] = variant->vertex_header_ptr_type;     /* vertex_header */
>     arg_types[3] = int32_type;                          /* num_prims */
>     arg_types[4] = int32_type;                          /* instance_id */
> +   arg_types[5] = LLVMPointerType(
> +      LLVMVectorType(int32_type, vector_length), 0);   /* prim_id_ptr */
>  
>     func_type = LLVMFunctionType(int32_type, arg_types, Elements(arg_types),
>     0);
>  
> @@ -1937,12 +1942,14 @@ draw_gs_llvm_generate(struct draw_llvm *llvm,
>     io_ptr                    = LLVMGetParam(variant_func, 2);
>     num_prims                 = LLVMGetParam(variant_func, 3);
>     system_values.instance_id = LLVMGetParam(variant_func, 4);
> +   prim_id_ptr               = LLVMGetParam(variant_func, 5);
>  
>     lp_build_name(context_ptr, "context");
>     lp_build_name(input_array, "input");
>     lp_build_name(io_ptr, "io");
>     lp_build_name(io_ptr, "num_prims");
>     lp_build_name(system_values.instance_id, "instance_id");
> +   lp_build_name(prim_id_ptr, "prim_id_ptr");
>  
>     variant->context_ptr = context_ptr;
>     variant->io_ptr = io_ptr;
> @@ -1970,7 +1977,7 @@ draw_gs_llvm_generate(struct draw_llvm *llvm,
>     gs_type.sign = TRUE;     /* values are signed */
>     gs_type.norm = FALSE;    /* values are not limited to [0,1] or [-1,1] */
>     gs_type.width = 32;      /* 32-bit float */
> -   gs_type.length = variant->shader->base.vector_length;
> +   gs_type.length = vector_length;
>  
>     consts_ptr = draw_gs_jit_context_constants(variant->gallivm,
>     context_ptr);
>  
> @@ -1981,6 +1988,10 @@ draw_gs_llvm_generate(struct draw_llvm *llvm,
>     mask_val = generate_mask_value(variant, gs_type);
>     lp_build_mask_begin(&mask, gallivm, gs_type, mask_val);
>  
> +   if (gs_info->uses_primid) {
> +      system_values.prim_id = LLVMBuildLoad(builder, prim_id_ptr,
> "prim_id");;
> +   }
> +
>     lp_build_tgsi_soa(variant->gallivm,
>                       tokens,
>                       gs_type,
> diff --git a/src/gallium/auxiliary/draw/draw_llvm.h
> b/src/gallium/auxiliary/draw/draw_llvm.h
> index 84ee601..8df02a2 100644
> --- a/src/gallium/auxiliary/draw/draw_llvm.h
> +++ b/src/gallium/auxiliary/draw/draw_llvm.h
> @@ -265,7 +265,8 @@ typedef int
>                      float
>                      inputs[6][PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS][TGSI_NUM_CHANNELS],
>                      struct vertex_header *output,
>                      unsigned num_prims,
> -                    unsigned instance_id);
> +                    unsigned instance_id,
> +                    int *prim_ids);
>  
>  struct draw_llvm_variant_key
>  {
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> index 5764847..558a8dd 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> @@ -155,6 +155,7 @@ struct lp_tgsi_info
>  struct lp_bld_tgsi_system_values {
>     LLVMValueRef instance_id;
>     LLVMValueRef vertex_id;
> +   LLVMValueRef prim_id;
>  };
>  
>  
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> index af3140c..81fa217 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> @@ -929,6 +929,11 @@ emit_fetch_system_value(
>        atype = TGSI_TYPE_UNSIGNED;
>        break;
>  
> +   case TGSI_SEMANTIC_PRIMID:
> +      res = bld->system_values.prim_id;
> +      atype = TGSI_TYPE_UNSIGNED;
> +      break;
> +
>     default:
>        assert(!"unexpected semantic in emit_fetch_system_value");
>        res = bld_base->base.zero;
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c
> b/src/gallium/auxiliary/tgsi/tgsi_scan.c
> index c59b3a7..373391d 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_scan.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c
> @@ -186,6 +186,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
>                    }
>                    else if (fulldecl->Semantic.Name ==
>                    TGSI_SEMANTIC_VERTEXID) {
>                       info->uses_vertexid = TRUE;
> +                  } else if (fulldecl->Semantic.Name ==
> TGSI_SEMANTIC_PRIMID) {
> +                     info->uses_primid = 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 235e6a3..9debc34 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_scan.h
> +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.h
> @@ -71,6 +71,7 @@ struct tgsi_shader_info
>     boolean uses_kill;  /**< KIL or KILP instruction used? */
>     boolean uses_instanceid;
>     boolean uses_vertexid;
> +   boolean uses_primid;
>     boolean origin_lower_left;
>     boolean pixel_center_integer;
>     boolean color0_writes_all_cbufs;


Looks good to me.

Reviewed-by: Jose Fonseca <jfonseca at vmware.com>


More information about the mesa-dev mailing list