summaryrefslogtreecommitdiff
path: root/src/gallium
diff options
context:
space:
mode:
authorZack Rusin <zackr@vmware.com>2010-04-28 17:11:25 -0400
committerZack Rusin <zackr@vmware.com>2010-04-29 11:53:32 -0400
commitb7618c89b11a13de98f1e784338a4e02a8db0fd2 (patch)
tree99619e7bd1fb68bfb9b4b07404b1c9337ab192e0 /src/gallium
parent4ccee747257192ef584d26d8854f8bc17cc57284 (diff)
draw llvm: stay in bounds even if fetch_count % 4 != 0
if fetch_count % 4 != 0 then on the last iteration we fetch garbage. this patch makes sure we stay within bounds
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index 27383221b9..3b2df054c3 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -713,10 +713,12 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
struct draw_context *draw = llvm->draw;
unsigned i, j;
struct lp_build_context bld;
+ struct lp_build_context bld_int;
struct lp_build_loop_state lp_loop;
struct lp_type vs_type = lp_type_float_vec(32);
const int max_vertices = 4;
LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
+ LLVMValueRef fetch_max;
arg_types[0] = llvm->context_ptr_type; /* context */
arg_types[1] = llvm->vertex_header_ptr_type; /* vertex_header */
@@ -759,9 +761,14 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
LLVMPositionBuilderAtEnd(builder, block);
lp_build_context_init(&bld, builder, vs_type);
+ lp_build_context_init(&bld_int, builder, lp_type_int(32));
step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0);
+ fetch_max = LLVMBuildSub(builder, fetch_count,
+ LLVMConstInt(LLVMInt32Type(), 1, 0),
+ "fetch_max");
+
lp_build_loop_begin(builder, LLVMConstInt(LLVMInt32Type(), 0, 0), &lp_loop);
{
LLVMValueRef inputs[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
@@ -780,8 +787,15 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
builder,
lp_loop.counter,
LLVMConstInt(LLVMInt32Type(), i, 0), "");
- LLVMValueRef fetch_ptr = LLVMBuildGEP(builder, fetch_elts,
- &true_index, 1, "");
+ LLVMValueRef fetch_ptr;
+
+ /* 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_int, true_index, fetch_max);
+
+ fetch_ptr = LLVMBuildGEP(builder, fetch_elts,
+ &true_index, 1, "");
true_index = LLVMBuildLoad(builder, fetch_ptr, "fetch_elt");
for (j = 0; j < draw->pt.nr_vertex_elements; ++j) {
struct pipe_vertex_element *velem = &draw->pt.vertex_element[j];