We can save a bunch of computations in the LLVM code for constant elemens. --- src/gallium/auxiliary/draw/draw_llvm.c | 54 +++++++++++++++------------ src/gallium/auxiliary/draw/draw_pt.c | 15 ++++--- src/gallium/auxiliary/draw/draw_pt_vcache.c | 2 +- 3 files changed, 40 insertions(+), 31 deletions(-)
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 8d53601..2ed5b25 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -389,36 +389,42 @@ generate_fetch(LLVMBuilderRef builder, LLVMValueRef indices = LLVMConstInt(LLVMInt64Type(), velem->vertex_buffer_index, 0); LLVMValueRef vbuffer_ptr = LLVMBuildGEP(builder, vbuffers_ptr, &indices, 1, ""); - LLVMValueRef vb_stride = draw_jit_vbuffer_stride(builder, vbuf); - LLVMValueRef vb_max_index = draw_jit_vbuffer_max_index(builder, vbuf); LLVMValueRef vb_buffer_offset = draw_jit_vbuffer_offset(builder, vbuf); - LLVMValueRef cond; - LLVMValueRef stride; - - if (velem->instance_divisor) { - /* array index = instance_id / instance_divisor */ - index = LLVMBuildUDiv(builder, instance_id, - LLVMConstInt(LLVMInt32Type(), velem->instance_divisor, 0), - "instance_divisor"); - } + LLVMValueRef offset; - /* limit index to min(inex, vb_max_index) */ - cond = LLVMBuildICmp(builder, LLVMIntULE, index, vb_max_index, ""); - index = LLVMBuildSelect(builder, cond, index, vb_max_index, ""); + vbuffer_ptr = LLVMBuildLoad(builder, vbuffer_ptr, "vbuffer"); - stride = LLVMBuildMul(builder, vb_stride, index, ""); + offset = LLVMConstInt(LLVMInt32Type(), velem->src_offset, 0); - vbuffer_ptr = LLVMBuildLoad(builder, vbuffer_ptr, "vbuffer"); + offset = LLVMBuildAdd(builder, offset, + vb_buffer_offset, + ""); - stride = LLVMBuildAdd(builder, stride, - vb_buffer_offset, - ""); - stride = LLVMBuildAdd(builder, stride, - LLVMConstInt(LLVMInt32Type(), velem->src_offset, 0), - ""); + if(velem->frequency != PIPE_ELEMENT_FREQUENCY_CONSTANT) + { + LLVMValueRef vb_stride = draw_jit_vbuffer_stride(builder, vbuf); + LLVMValueRef vb_max_index = draw_jit_vbuffer_max_index(builder, vbuf); + LLVMValueRef cond; + LLVMValueRef variable_offset; + + if (velem->frequency == PIPE_ELEMENT_FREQUENCY_PER_INSTANCE) { + /* array index = instance_id / instance_divisor */ + index = LLVMBuildUDiv(builder, instance_id, + LLVMConstInt(LLVMInt32Type(), velem->instance_divisor, 0), + "instance_divisor"); + } + + /* limit index to min(inex, vb_max_index) */ + cond = LLVMBuildICmp(builder, LLVMIntULE, index, vb_max_index, ""); + index = LLVMBuildSelect(builder, cond, index, vb_max_index, ""); + + variable_offset = LLVMBuildMul(builder, vb_stride, index, ""); + offset = LLVMBuildAdd(builder, offset, variable_offset, ""); + + /*lp_build_printf(builder, "vbuf index = %d, stride is %d\n", indices, stride);*/ + } - /*lp_build_printf(builder, "vbuf index = %d, stride is %d\n", indices, stride);*/ - vbuffer_ptr = LLVMBuildGEP(builder, vbuffer_ptr, &stride, 1, ""); + vbuffer_ptr = LLVMBuildGEP(builder, vbuffer_ptr, &offset, 1, ""); *res = draw_llvm_translate_from(builder, vbuffer_ptr, velem->src_format); } diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 2489275..4b58899 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -260,12 +260,13 @@ draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count) uint buf = draw->pt.vertex_element[j].vertex_buffer_index; ubyte *ptr = (ubyte *) draw->pt.user.vbuffer[buf]; - if (draw->pt.vertex_element[j].instance_divisor) { - ii = draw->instance_id / draw->pt.vertex_element[j].instance_divisor; - } - ptr += draw->pt.vertex_buffer[buf].buffer_offset; - ptr += draw->pt.vertex_buffer[buf].stride * ii; + + if (draw->pt.vertex_element[j].frequency == PIPE_ELEMENT_FREQUENCY_PER_INSTANCE) + ptr += draw->pt.vertex_buffer[buf].stride * (draw->instance_id / draw->pt.vertex_element[j].instance_divisor); + else if (draw->pt.vertex_element[j].frequency == PIPE_ELEMENT_FREQUENCY_PER_VERTEX) + ptr += draw->pt.vertex_buffer[buf].stride * ii; + ptr += draw->pt.vertex_element[j].src_offset; debug_printf(" Attr %u: ", j); @@ -363,11 +364,13 @@ draw_arrays_instanced(struct draw_context *draw, if (0) { unsigned int i; + const char* frequency_names[] = {"per-vertex", "per-instance", "constant"}; debug_printf("Elements:\n"); for (i = 0; i < draw->pt.nr_vertex_elements; i++) { - debug_printf(" %u: src_offset=%u inst_div=%u vbuf=%u format=%s\n", + debug_printf(" %u: src_offset=%u frequency=%s inst_div=%u vbuf=%u format=%s\n", i, draw->pt.vertex_element[i].src_offset, + frequency_names[draw->pt.vertex_element[i].frequency], draw->pt.vertex_element[i].instance_divisor, draw->pt.vertex_element[i].vertex_buffer_index, util_format_name(draw->pt.vertex_element[i].src_format)); diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index a848b54..a41ed61 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -358,7 +358,7 @@ any_instance_divisors(const struct draw_context *draw) uint i; for (i = 0; i < draw->pt.nr_vertex_elements; i++) { - uint div = draw->pt.vertex_element[i].instance_divisor; + uint div = draw->pt.vertex_element[i].frequency == PIPE_ELEMENT_FREQUENCY_PER_INSTANCE; if (div) return TRUE; } -- 1.7.0.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev