diff options
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 10 | ||||
-rw-r--r-- | src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 1 | ||||
-rw-r--r-- | src/gallium/auxiliary/translate/translate_sse.c | 19 |
3 files changed, 28 insertions, 2 deletions
diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index b03dd3a0cf8..5231bb08374 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -726,6 +726,16 @@ void x86_movzx16(struct x86_function *p, struct x86_reg dst, struct x86_reg src emit_modrm(p, dst, src); } +void x86_cmovcc( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src, + enum x86_cc cc) +{ + DUMP_RRI( dst, src, cc ); + emit_2ub( p, 0x0f, 0x40 + cc ); + emit_modrm( p, dst, src ); +} + void x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index 2b9678b1765..af0565bb59d 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -309,6 +309,7 @@ void sse_movmskps( struct x86_function *p, struct x86_reg dst, struct x86_reg sr void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_cmovcc( struct x86_function *p, struct x86_reg dst, struct x86_reg src, enum x86_cc cc ); void x86_cmp( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_dec( struct x86_function *p, struct x86_reg reg ); void x86_inc( struct x86_function *p, struct x86_reg reg ); diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c index ef7f4be4c3e..b00242d8b20 100644 --- a/src/gallium/auxiliary/translate/translate_sse.c +++ b/src/gallium/auxiliary/translate/translate_sse.c @@ -1067,6 +1067,8 @@ static boolean init_inputs( struct translate_sse *p, struct translate_buffer *buffer = &p->buffer[varient->buffer_index]; if (!index_size || varient->instance_divisor) { + struct x86_reg buf_max_index = x86_make_disp(p->machine_EDI, + get_offset(p, &buffer->max_index)); struct x86_reg buf_stride = x86_make_disp(p->machine_EDI, get_offset(p, &buffer->stride)); struct x86_reg buf_ptr = x86_make_disp(p->machine_EDI, @@ -1100,14 +1102,17 @@ static boolean init_inputs( struct translate_sse *p, x86_mov(p->func, tmp_EAX, elt); } - /* - * TODO: Respect translate_buffer::max_index. + /* Clamp to max_index */ + x86_cmp(p->func, tmp_EAX, buf_max_index); + x86_cmovcc(p->func, tmp_EAX, buf_max_index, cc_AE); x86_imul(p->func, tmp_EAX, buf_stride); x64_rexw(p->func); x86_add(p->func, tmp_EAX, buf_base_ptr); + x86_cmp(p->func, p->count_EBP, p->tmp_EAX); + /* In the linear case, keep the buffer pointer instead of the * index number. @@ -1163,6 +1168,10 @@ static struct x86_reg get_buffer_ptr( struct translate_sse *p, x86_make_disp(p->machine_EDI, get_offset(p, &p->buffer[varient->buffer_index].base_ptr)); + struct x86_reg buf_max_index = + x86_make_disp(p->machine_EDI, + get_offset(p, &p->buffer[varient->buffer_index].max_index)); + /* Calculate pointer to current attrib: @@ -1179,6 +1188,12 @@ static struct x86_reg get_buffer_ptr( struct translate_sse *p, x86_mov(p->func, ptr, elt); break; } + + /* Clamp to max_index + */ + x86_cmp(p->func, ptr, buf_max_index); + x86_cmovcc(p->func, ptr, buf_max_index, cc_AE); + x86_imul(p->func, ptr, buf_stride); x64_rexw(p->func); x86_add(p->func, ptr, buf_base_ptr); |