draw: Implement support for primitive id
authorZack Rusin <zackr@vmware.com>
Fri, 29 Mar 2013 11:50:32 +0000 (04:50 -0700)
committerZack Rusin <zackr@vmware.com>
Wed, 3 Apr 2013 17:16:25 +0000 (10:16 -0700)
We were largely ignoring primitive id.

Signed-off-by: Zack Rusin <zackr@vmware.com>
Reviewed-by: José Fonseca <jfonseca@vmware.com>
src/gallium/auxiliary/draw/draw_gs.c
src/gallium/auxiliary/draw/draw_gs.h
src/gallium/auxiliary/draw/draw_llvm.c
src/gallium/auxiliary/draw/draw_llvm.h
src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
src/gallium/auxiliary/tgsi/tgsi_scan.c
src/gallium/auxiliary/tgsi/tgsi_scan.h

index 378d1589606fff0b737b4428fa9ec3b22dc35d00..b98b1334002804b2ce01bf43308be3539e657efd 100644 (file)
@@ -225,6 +225,9 @@ llvm_fetch_gs_input(struct draw_geometry_shader *shader,
    const float (*input_ptr)[4];
    float (*input_data)[6][PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS][TGSI_NUM_CHANNELS] = &shader->gs_input->data;
 
+   shader->llvm_prim_ids[shader->fetched_prim_count] =
+      shader->in_prim_idx;
+
    input_ptr = shader->input;
 
    for (i = 0; i < num_vertices; ++i) {
@@ -237,10 +240,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 +343,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;
 }
@@ -728,6 +729,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 +798,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);
    }
index 9c826485aba1dbbb91625301981b283b72da48df..7c841396aa2f24c90f8ae9a39bd99b7f6b8ffca7 100644 (file)
@@ -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,
index 4731c8cbd825f9918186f1d14740bf79fd150f98..d0199bbc92a326fdb23a985506f207d6dc7d925d 100644 (file)
@@ -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,
index 84ee601e59dff5f442dec3fdc03669d6d275b33d..8df02a2b31089feb7728fc9f060a5a947b193b09 100644 (file)
@@ -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
 {
index 5764847acb5425cca2903fe209c541bf446d8080..558a8dd7dd8072fb0899ca5640d6afa9b2cc28d3 100644 (file)
@@ -155,6 +155,7 @@ struct lp_tgsi_info
 struct lp_bld_tgsi_system_values {
    LLVMValueRef instance_id;
    LLVMValueRef vertex_id;
+   LLVMValueRef prim_id;
 };
 
 
index 54f3fd9f8f80e0b6b49dc792eb18ef362add6a5b..e802d5b1b62b8ed09e414dd17e0ece3e40c48ecf 100644 (file)
@@ -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;
index c59b3a75bd920c7fe049c249f80ba4ec968f9c0f..373391d62c107defa74ba6f66adf94aae374ec09 100644 (file)
@@ -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) {
index 235e6a3fae0081afb387936b9da6f565bf19e712..9debc341f5242155a78d93786f475e50c42fbf1b 100644 (file)
@@ -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;