Implement instanced indexed draw.
authorMichal Krol <michal@vmware.com>
Wed, 30 Dec 2009 17:26:40 +0000 (18:26 +0100)
committerMichal Krol <michal@vmware.com>
Wed, 30 Dec 2009 17:26:40 +0000 (18:26 +0100)
src/gallium/auxiliary/draw/draw_pt_fetch.c
src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
src/gallium/auxiliary/draw/draw_vs_varient.c
src/gallium/auxiliary/translate/translate.h
src/gallium/auxiliary/translate/translate_generic.c
src/gallium/auxiliary/translate/translate_sse.c

index e8174a297116301dc62715893329afa714b76f02..f88a839f61e9fd286ea5c2a0a125c27e7349c57f 100644 (file)
@@ -160,6 +160,7 @@ void draw_pt_fetch_run( struct pt_fetch *fetch,
    translate->run_elts( translate,
                        elts, 
                        count,
+                        draw->instance_id,
                        verts );
 
 }
index 40bfc0fbb22795504da3603f9813aecce4a4a130..771d94b973c4a93bb22d79776da417efd1b7230f 100644 (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) {
index 4cc080f8039f320355ec25ab7ffa3eda880d2620..8e14bdd6bdead1547546e06c7192c0759f2c65ee 100644 (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, 
index fb298471b8bf29aeef71cfc82382fde385c9969c..9ae7a482a070e835d38ae6bf53f73048e8cced9c 100644 (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 *,
index 0fa99274099b31b07932e00a7ac3bcea968c7473..742f03b503183875ca68c8d32dac399ce1ca8727 100644 (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",
index ffc5fe9e818629ec4336c504a6841d1cfef4fcdc..ba4a246fdbf1c4f8e48b7983526b981ddc64d918 100644 (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 );
 }