Am 24.07.2013 23:22, schrieb Zack Rusin: > vertex id has to be unaffected by the start index (i.e. when calling > draw arrays with start_index = 5, the first vertex_id has to still > be 0, not 5) and it has to be equal to the index when performing > indexed rendering (in which case it has to be unaffected by the > index bias). This fixes our behavior. > > Signed-off-by: Zack Rusin <za...@vmware.com> > --- > src/gallium/auxiliary/draw/draw_llvm.c | 36 > +++++++++++++++----- > src/gallium/auxiliary/draw/draw_llvm.h | 6 ++-- > src/gallium/auxiliary/draw/draw_private.h | 1 + > src/gallium/auxiliary/draw/draw_pt.c | 1 + > .../draw/draw_pt_fetch_shade_pipeline_llvm.c | 6 ++-- > 5 files changed, 37 insertions(+), 13 deletions(-) > > diff --git a/src/gallium/auxiliary/draw/draw_llvm.c > b/src/gallium/auxiliary/draw/draw_llvm.c > index a3174b4..c195a2b 100644 > --- a/src/gallium/auxiliary/draw/draw_llvm.c > +++ b/src/gallium/auxiliary/draw/draw_llvm.c > @@ -1486,7 +1486,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct > draw_llvm_variant *variant, > struct gallivm_state *gallivm = variant->gallivm; > LLVMContextRef context = gallivm->context; > LLVMTypeRef int32_type = LLVMInt32TypeInContext(context); > - LLVMTypeRef arg_types[9]; > + LLVMTypeRef arg_types[10]; > unsigned num_arg_types = > elts ? Elements(arg_types) : Elements(arg_types) - 1; > LLVMTypeRef func_type; > @@ -1496,6 +1496,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct > draw_llvm_variant *variant, > struct lp_type vs_type; > LLVMValueRef end, start; > LLVMValueRef count, fetch_elts, fetch_elt_max, fetch_count; > + LLVMValueRef vertex_id_offset; > LLVMValueRef stride, step, io_itr; > LLVMValueRef io_ptr, vbuffers_ptr, vb_ptr; > LLVMValueRef zero = lp_build_const_int32(gallivm, 0); > @@ -1541,6 +1542,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct > draw_llvm_variant *variant, > arg_types[i++] = int32_type; /* stride */ > arg_types[i++] = get_vb_ptr_type(variant); /* pipe_vertex_buffer's > */ > arg_types[i++] = int32_type; /* instance_id */ > + arg_types[i++] = int32_type; /* vertex_id_offset */ > > func_type = LLVMFunctionType(int32_type, arg_types, num_arg_types, 0); > > @@ -1565,6 +1567,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct > draw_llvm_variant *variant, > stride = LLVMGetParam(variant_func, 5 + (elts ? 1 : > 0)); > vb_ptr = LLVMGetParam(variant_func, 6 + (elts ? 1 : > 0)); > system_values.instance_id = LLVMGetParam(variant_func, 7 + (elts ? 1 : > 0)); > + vertex_id_offset = LLVMGetParam(variant_func, 8 + (elts ? 1 : > 0)); > > lp_build_name(context_ptr, "context"); > lp_build_name(io_ptr, "io"); > @@ -1572,6 +1575,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct > draw_llvm_variant *variant, > lp_build_name(stride, "stride"); > lp_build_name(vb_ptr, "vb"); > lp_build_name(system_values.instance_id, "instance_id"); > + lp_build_name(vertex_id_offset, "vertex_id_offset"); > > if (elts) { > fetch_elts = LLVMGetParam(variant_func, 3); > @@ -1646,22 +1650,19 @@ draw_llvm_generate(struct draw_llvm *llvm, struct > draw_llvm_variant *variant, > #endif > system_values.vertex_id = lp_build_zero(gallivm, lp_type_uint_vec(32, > 32*vector_length)); > for (i = 0; i < vector_length; ++i) { > - LLVMValueRef true_index = > + LLVMValueRef vert_index = > LLVMBuildAdd(builder, > lp_loop.counter, > lp_build_const_int32(gallivm, i), ""); > - true_index = LLVMBuildAdd(builder, start, true_index, ""); > + LLVMValueRef true_index = > + LLVMBuildAdd(builder, start, vert_index, ""); > + LLVMValueRef vertex_id; > > /* make sure we're not out of bounds which can happen > * if fetch_count % 4 != 0, because on the last iteration > * a few of the 4 vertex fetches will be out of bounds */ > true_index = lp_build_min(&bld, true_index, fetch_max); > > - system_values.vertex_id = LLVMBuildInsertElement( > - gallivm->builder, > - system_values.vertex_id, true_index, > - lp_build_const_int32(gallivm, i), ""); > - > if (elts) { > LLVMValueRef fetch_ptr; > LLVMValueRef index_overflowed; > @@ -1673,7 +1674,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct > draw_llvm_variant *variant, > index_overflowed = LLVMBuildICmp(builder, LLVMIntUGT, > true_index, fetch_elt_max, > "index_overflowed"); > - > + > lp_build_if(&if_ctx, gallivm, index_overflowed); > { > /* Generate maximum possible index so that > @@ -1698,6 +1699,23 @@ draw_llvm_generate(struct draw_llvm *llvm, struct > draw_llvm_variant *variant, > lp_build_endif(&if_ctx); > true_index = LLVMBuildLoad(builder, index_ptr, "true_index"); > } > + /* in the paths with elts vertex id has to be unaffected by the > + * index bias and because indices inside our elements array have > + * already had index bias applied we need to subtract it here to > + * get back to the original index. > + * in the linear paths vertex id has to be unaffected by the > + * original start index and because we abuse the 'start' variable > + * to either represent the actual start index or the index at which > + * the primitive was split (we split rendering into chunks of at > + * most 4095-vertices) we need to back out the original start > + * index out of our vertex id here. > + */ > + vertex_id = LLVMBuildSub(builder, true_index, vertex_id_offset, ""); > + > + system_values.vertex_id = LLVMBuildInsertElement( > + gallivm->builder, > + system_values.vertex_id, vertex_id, > + lp_build_const_int32(gallivm, i), ""); > > for (j = 0; j < draw->pt.nr_vertex_elements; ++j) { > struct pipe_vertex_element *velem = &draw->pt.vertex_element[j]; > diff --git a/src/gallium/auxiliary/draw/draw_llvm.h > b/src/gallium/auxiliary/draw/draw_llvm.h > index 347fde2..0675e3b 100644 > --- a/src/gallium/auxiliary/draw/draw_llvm.h > +++ b/src/gallium/auxiliary/draw/draw_llvm.h > @@ -263,7 +263,8 @@ typedef int > unsigned count, > unsigned stride, > struct pipe_vertex_buffer *vertex_buffers, > - unsigned instance_id); > + unsigned instance_id, > + unsigned vertex_id_offset); > > > typedef int > @@ -275,7 +276,8 @@ typedef int > unsigned fetch_count, > unsigned stride, > struct pipe_vertex_buffer *vertex_buffers, > - unsigned instance_id); > + unsigned instance_id, > + unsigned vertex_id_offset); > > > typedef int > diff --git a/src/gallium/auxiliary/draw/draw_private.h > b/src/gallium/auxiliary/draw/draw_private.h > index d8cd8eb..868b6c7 100644 > --- a/src/gallium/auxiliary/draw/draw_private.h > +++ b/src/gallium/auxiliary/draw/draw_private.h > @@ -311,6 +311,7 @@ struct draw_context > > unsigned instance_id; > unsigned start_instance; > + unsigned start_index; > > #ifdef HAVE_LLVM > struct draw_llvm *llvm; > diff --git a/src/gallium/auxiliary/draw/draw_pt.c > b/src/gallium/auxiliary/draw/draw_pt.c > index fcc2405..5b16bc7 100644 > --- a/src/gallium/auxiliary/draw/draw_pt.c > +++ b/src/gallium/auxiliary/draw/draw_pt.c > @@ -535,6 +535,7 @@ draw_vbo(struct draw_context *draw, > } > > draw->pt.max_index = index_limit - 1; > + draw->start_index = info->start; > > /* > * TODO: We could use draw->pt.max_index to further narrow > diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c > b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c > index 2e47fad..17b948a 100644 > --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c > +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c > @@ -353,7 +353,8 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle, > fetch_info->count, > fpme->vertex_size, > draw->pt.vertex_buffer, > - draw->instance_id); > + draw->instance_id, > + draw->start_index); > else > clipped = fpme->current_variant->jit_func_elts( > &fpme->llvm->jit_context, > llvm_vert_info.verts, > @@ -363,7 +364,8 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle, > fetch_info->count, > fpme->vertex_size, > draw->pt.vertex_buffer, > - draw->instance_id); > + draw->instance_id, > + draw->pt.user.eltBias); > > /* Finished with fetch and vs: > */ >
LGTM. Is that handled correctly in the non-llvm path already? Roland _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev