[Mesa-dev] [PATCH 4/4] draw: optimize for vertex element frequency (esp. draw_llvm)
Luca Barbieri
luca at luca-barbieri.com
Mon Aug 16 04:30:09 PDT 2010
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
More information about the mesa-dev
mailing list