From: Zack Rusin Date: Fri, 29 Mar 2013 11:50:32 +0000 (-0700) Subject: draw: Implement support for primitive id X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d8543bd7528de05e5ce3ac407838e7500428a93d;p=mesa.git draw: Implement support for primitive id We were largely ignoring primitive id. Signed-off-by: Zack Rusin Reviewed-by: José Fonseca --- diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c index 378d1589606..b98b1334002 100644 --- a/src/gallium/auxiliary/draw/draw_gs.c +++ b/src/gallium/auxiliary/draw/draw_gs.c @@ -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); } diff --git a/src/gallium/auxiliary/draw/draw_gs.h b/src/gallium/auxiliary/draw/draw_gs.h index 9c826485aba..7c841396aa2 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 4731c8cbd82..d0199bbc92a 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 84ee601e59d..8df02a2b310 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 5764847acb5..558a8dd7dd8 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 54f3fd9f8f8..e802d5b1b62 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 c59b3a75bd9..373391d62c1 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 235e6a3fae0..9debc341f52 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;