tnl: implement instanced drawing
authorBrian Paul <brianp@vmware.com>
Fri, 10 Dec 2010 16:29:13 +0000 (09:29 -0700)
committerBrian Paul <brianp@vmware.com>
Fri, 10 Dec 2010 16:29:13 +0000 (09:29 -0700)
src/mesa/tnl/t_context.h
src/mesa/tnl/t_draw.c
src/mesa/tnl/t_vb_program.c

index bc01646247cebd777b7961a4192fafcf87f8cfc3..6a9444216c0db20d5e5b3f6203444bdee3e3fab1 100644 (file)
@@ -527,6 +527,8 @@ typedef struct
    GLubyte *block[VERT_ATTRIB_MAX];
    GLuint nr_blocks;
 
+   GLuint CurInstance;
+
 } TNLcontext;
 
 
index 30f1bf323cbea3880800d6481282f32b837725a9..bdb893eba222e9b86f9555bcd9dc25e81dd26428 100644 (file)
@@ -453,6 +453,7 @@ void _tnl_draw_prims( struct gl_context *ctx,
        */
       struct gl_buffer_object *bo[VERT_ATTRIB_MAX + 1];
       GLuint nr_bo = 0;
+      GLuint inst;
 
       for (i = 0; i < nr_prims;) {
         GLuint this_nr_prims;
@@ -470,15 +471,19 @@ void _tnl_draw_prims( struct gl_context *ctx,
         /* Binding inputs may imply mapping some vertex buffer objects.
          * They will need to be unmapped below.
          */
-        bind_prims(ctx, &prim[i], this_nr_prims);
-        bind_inputs(ctx, arrays, max_index + prim[i].basevertex + 1,
-                    bo, &nr_bo);
-        bind_indices(ctx, ib, bo, &nr_bo);
+         for (inst = 0; inst < prim[i].num_instances; inst++) {
 
-        TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);
+            bind_prims(ctx, &prim[i], this_nr_prims);
+            bind_inputs(ctx, arrays, max_index + prim[i].basevertex + 1,
+                        bo, &nr_bo);
+            bind_indices(ctx, ib, bo, &nr_bo);
 
-        unmap_vbos(ctx, bo, nr_bo);
-        free_space(ctx);
+            tnl->CurInstance = inst;
+            TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);
+
+            unmap_vbos(ctx, bo, nr_bo);
+            free_space(ctx);
+         }
 
         i += this_nr_prims;
       }
index 76f8fde3f5203db77cd912d18e9a8ac95139ecc5..a1853689a437a568b1a3bbf554d2e46c14787ba8 100644 (file)
@@ -218,7 +218,8 @@ _tnl_program_string(struct gl_context *ctx, GLenum target, struct gl_program *pr
  * Initialize virtual machine state prior to executing vertex program.
  */
 static void
-init_machine(struct gl_context *ctx, struct gl_program_machine *machine)
+init_machine(struct gl_context *ctx, struct gl_program_machine *machine,
+             GLuint instID)
 {
    /* Input registers get initialized from the current vertex attribs */
    memcpy(machine->VertAttribs, ctx->Current.Attrib,
@@ -254,6 +255,8 @@ init_machine(struct gl_context *ctx, struct gl_program_machine *machine)
    machine->FetchTexelDeriv = NULL; /* not used by vertex programs */
 
    machine->Samplers = ctx->VertexProgram._Current->Base.SamplerUnits;
+
+   machine->SystemValues[SYSTEM_VALUE_INSTANCE_ID][0] = (GLfloat) instID;
 }
 
 
@@ -339,7 +342,7 @@ run_vp( struct gl_context *ctx, struct tnl_pipeline_stage *stage )
    for (i = 0; i < VB->Count; i++) {
       GLuint attr;
 
-      init_machine(ctx, &machine);
+      init_machine(ctx, &machine, tnl->CurInstance);
 
 #if 0
       printf("Input  %d: %f, %f, %f, %f\n", i,