Implement instanced indexed draw.

This commit is contained in:
Michal Krol 2009-12-30 18:26:40 +01:00
parent 76e53923ba
commit 5007e39f76
6 changed files with 26 additions and 12 deletions

View file

@ -160,6 +160,7 @@ void draw_pt_fetch_run( struct pt_fetch *fetch,
translate->run_elts( translate,
elts,
count,
draw->instance_id,
verts );
}

View file

@ -257,6 +257,7 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle,
feme->translate->run_elts( feme->translate,
fetch_elts,
fetch_count,
draw->instance_id,
hw_verts );
if (0) {

View file

@ -142,6 +142,7 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient,
vsvg->fetch->run_elts( vsvg->fetch,
elts,
count,
vsvg->draw->instance_id,
temp_buffer );
vsvg->base.vs->run_linear( vsvg->base.vs,

View file

@ -75,6 +75,7 @@ struct translate {
void (PIPE_CDECL *run_elts)( struct translate *,
const unsigned *elts,
unsigned count,
unsigned instance_id,
void *output_buffer);
void (PIPE_CDECL *run)( struct translate *,

View file

@ -569,6 +569,7 @@ static emit_func get_emit_func( enum pipe_format format )
static void PIPE_CDECL generic_run_elts( struct translate *translate,
const unsigned *elts,
unsigned count,
unsigned instance_id,
void *output_buffer )
{
struct translate_generic *tg = translate_generic(translate);
@ -584,13 +585,20 @@ static void PIPE_CDECL generic_run_elts( struct translate *translate,
for (attr = 0; attr < nr_attrs; attr++) {
float data[4];
const char *src = (tg->attrib[attr].input_ptr +
tg->attrib[attr].input_stride * elt);
const char *src;
char *dst = (vert +
tg->attrib[attr].output_offset);
if (tg->attrib[attr].instance_divisor) {
src = tg->attrib[attr].input_ptr +
tg->attrib[attr].input_stride *
(instance_id / tg->attrib[attr].instance_divisor);
} else {
src = tg->attrib[attr].input_ptr +
tg->attrib[attr].input_stride * elt;
}
tg->attrib[attr].fetch( src, data );
if (0) debug_printf("vert %d/%d attr %d: %f %f %f %f\n",

View file

@ -376,13 +376,14 @@ static boolean init_inputs( struct translate_sse *p,
boolean linear )
{
unsigned i;
if (linear) {
struct x86_reg instance_id = x86_make_disp(p->machine_EDX,
get_offset(p, &p->instance_id));
struct x86_reg instance_id = x86_make_disp(p->machine_EDX,
get_offset(p, &p->instance_id));
for (i = 0; i < p->nr_buffer_varients; i++) {
struct translate_buffer_varient *varient = &p->buffer_varient[i];
struct translate_buffer *buffer = &p->buffer[varient->buffer_index];
for (i = 0; i < p->nr_buffer_varients; i++) {
struct translate_buffer_varient *varient = &p->buffer_varient[i];
struct translate_buffer *buffer = &p->buffer[varient->buffer_index];
if (linear || varient->instance_divisor) {
struct x86_reg buf_stride = x86_make_disp(p->machine_EDX,
get_offset(p, &buffer->stride));
struct x86_reg buf_ptr = x86_make_disp(p->machine_EDX,
@ -426,7 +427,7 @@ static boolean init_inputs( struct translate_sse *p,
/* In the linear case, keep the buffer pointer instead of the
* index number.
*/
if (p->nr_buffer_varients == 1)
if (linear && p->nr_buffer_varients == 1)
x86_mov(p->func, elt, tmp_EAX);
else
x86_mov(p->func, buf_ptr, tmp_EAX);
@ -445,7 +446,7 @@ static struct x86_reg get_buffer_ptr( struct translate_sse *p,
if (linear && p->nr_buffer_varients == 1) {
return p->idx_EBX;
}
else if (linear) {
else if (linear || p->buffer_varient[var_idx].instance_divisor) {
struct x86_reg ptr = p->tmp_EAX;
struct x86_reg buf_ptr =
x86_make_disp(p->machine_EDX,
@ -687,6 +688,7 @@ static void translate_sse_release( struct translate *translate )
static void PIPE_CDECL translate_sse_run_elts( struct translate *translate,
const unsigned *elts,
unsigned count,
unsigned instance_id,
void *output_buffer )
{
struct translate_sse *p = (struct translate_sse *)translate;
@ -694,7 +696,7 @@ static void PIPE_CDECL translate_sse_run_elts( struct translate *translate,
p->gen_run_elts( translate,
elts,
count,
0,
instance_id,
output_buffer );
}