summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Krol <[email protected]>2009-12-30 18:26:40 +0100
committerMichal Krol <[email protected]>2009-12-30 18:26:40 +0100
commit5007e39f76c897b8f3aa4acf6086c8b7ac30bdef (patch)
treed971e3535c0162a9d0c2fa5ecc066e446d7fc068
parent76e53923ba79124c6df55bddd7e9a11a7e9104d4 (diff)
Implement instanced indexed draw.
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch.c1
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_emit.c1
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_varient.c1
-rw-r--r--src/gallium/auxiliary/translate/translate.h1
-rw-r--r--src/gallium/auxiliary/translate/translate_generic.c14
-rw-r--r--src/gallium/auxiliary/translate/translate_sse.c20
6 files changed, 26 insertions, 12 deletions
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c
index e8174a29711..f88a839f61e 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c
@@ -160,6 +160,7 @@ void draw_pt_fetch_run( struct pt_fetch *fetch,
translate->run_elts( translate,
elts,
count,
+ draw->instance_id,
verts );
}
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
index 40bfc0fbb22..771d94b973c 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
@@ -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) {
diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c
index 4cc080f8039..8e14bdd6bde 100644
--- a/src/gallium/auxiliary/draw/draw_vs_varient.c
+++ b/src/gallium/auxiliary/draw/draw_vs_varient.c
@@ -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,
diff --git a/src/gallium/auxiliary/translate/translate.h b/src/gallium/auxiliary/translate/translate.h
index fb298471b8b..9ae7a482a07 100644
--- a/src/gallium/auxiliary/translate/translate.h
+++ b/src/gallium/auxiliary/translate/translate.h
@@ -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 *,
diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c
index 0fa99274099..742f03b5031 100644
--- a/src/gallium/auxiliary/translate/translate_generic.c
+++ b/src/gallium/auxiliary/translate/translate_generic.c
@@ -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",
diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c
index ffc5fe9e818..ba4a246fdbf 100644
--- a/src/gallium/auxiliary/translate/translate_sse.c
+++ b/src/gallium/auxiliary/translate/translate_sse.c
@@ -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 );
}