draw: account for elem size when computing overflow

We weren't taking into account the size of element
that is to be fetched, which meant that it was possible
to overflow the buffer reads if the stride was very
close to the end of the buffer, e.g. stride = 3, buffer
size = 4, and the element to be read = 4. This should
be properly detected as an overflow.

Signed-off-by: Zack Rusin <zackr@vmware.com>
This commit is contained in:
Zack Rusin 2013-06-25 13:54:47 -04:00
parent 7214fe3cc4
commit e742f7788e

View file

@ -695,6 +695,7 @@ generate_fetch(struct gallivm_state *gallivm,
LLVMValueRef buffer_size = draw_jit_dvbuffer_size(gallivm, vbuffer_ptr); LLVMValueRef buffer_size = draw_jit_dvbuffer_size(gallivm, vbuffer_ptr);
LLVMValueRef stride; LLVMValueRef stride;
LLVMValueRef buffer_overflowed; LLVMValueRef buffer_overflowed;
LLVMValueRef needed_buffer_size;
LLVMValueRef temp_ptr = LLVMValueRef temp_ptr =
lp_build_alloca(gallivm, lp_build_alloca(gallivm,
lp_build_vec_type(gallivm, lp_float32_vec4_type()), ""); lp_build_vec_type(gallivm, lp_float32_vec4_type()), "");
@ -715,15 +716,30 @@ generate_fetch(struct gallivm_state *gallivm,
stride = LLVMBuildAdd(builder, stride, stride = LLVMBuildAdd(builder, stride,
lp_build_const_int32(gallivm, velem->src_offset), lp_build_const_int32(gallivm, velem->src_offset),
""); "");
needed_buffer_size = LLVMBuildAdd(
builder, stride,
lp_build_const_int32(gallivm,
util_format_get_blocksize(velem->src_format)),
"");
buffer_overflowed = LLVMBuildICmp(builder, LLVMIntUGE, buffer_overflowed = LLVMBuildICmp(builder, LLVMIntUGT,
stride, buffer_size, needed_buffer_size, buffer_size,
"buffer_overflowed"); "buffer_overflowed");
/* #if 0
lp_build_printf(gallivm, "vbuf index = %u, stride is %u\n", index, stride); lp_build_printf(gallivm, "vbuf index = %u, vb_stride is %u\n",
lp_build_print_value(gallivm, " buffer size = ", buffer_size); index, vb_stride);
lp_build_printf(gallivm, " vb_buffer_offset = %u, src_offset is %u\n",
vb_buffer_offset,
lp_build_const_int32(gallivm, velem->src_offset));
lp_build_print_value(gallivm, " blocksize = ",
lp_build_const_int32(
gallivm,
util_format_get_blocksize(velem->src_format)));
lp_build_printf(gallivm, " stride = %u\n", stride);
lp_build_printf(gallivm, " buffer size = %u\n", buffer_size);
lp_build_printf(gallivm, " needed_buffer_size = %u\n", needed_buffer_size);
lp_build_print_value(gallivm, " buffer overflowed = ", buffer_overflowed); lp_build_print_value(gallivm, " buffer overflowed = ", buffer_overflowed);
*/ #endif
lp_build_if(&if_ctx, gallivm, buffer_overflowed); lp_build_if(&if_ctx, gallivm, buffer_overflowed);
{ {