tnl: Add a utility to emit indexed vertices to a DMA buffer.
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Tue, 20 Jan 2009 10:15:57 +0000 (11:15 +0100)
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Tue, 20 Jan 2009 10:15:57 +0000 (11:15 +0100)
This utility is useful for hardware that doesn't support HW index buffers.
It's a bit inefficient but appears to give a substantial performance gain,
as we can emit tri strips that would otherwise be split into triangles.

src/mesa/tnl/t_vertex.c
src/mesa/tnl/t_vertex.h

index b661524c87088913c399bdc29989da3c0c728191..10b78f820ea8bedfa230150679728c42e0b51eab 100644 (file)
@@ -376,6 +376,22 @@ void _tnl_notify_pipeline_output_change( GLcontext *ctx )
    invalidate_funcs(vtx);
 }
 
+
+static void adjust_input_ptrs( GLcontext *ctx, GLint diff)
+{
+   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+   struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
+   struct tnl_clipspace_attr *a = vtx->attr;
+   const GLuint count = vtx->attr_count;
+   int j;
+
+   diff -= 1;
+   for (j=0; j<count; ++j) {
+           register GLvector4f *vptr = VB->AttribPtr[a->attrib];
+          (a++)->inputptr += diff*vptr->stride;
+   }
+}
+
 static void update_input_ptrs( GLcontext *ctx, GLuint start )
 {
    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
@@ -431,13 +447,40 @@ void *_tnl_emit_vertices_to_buffer( GLcontext *ctx,
    struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
 
    update_input_ptrs(ctx, start);
-
    /* Note: dest should not be adjusted for non-zero 'start' values:
     */
    vtx->emit( ctx, end - start, (GLubyte*) dest );     
    return (void *)((GLubyte *)dest + vtx->vertex_size * (end - start));
 }
 
+/* Emit indexed VB vertices start..end to dest.  Note that VB vertex at
+ * postion start will be emitted to dest at position zero.
+ */
+
+void *_tnl_emit_indexed_vertices_to_buffer( GLcontext *ctx,
+                                           const GLuint *elts,
+                                           GLuint start,
+                                           GLuint end,
+                                           void *dest )
+{
+   struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
+   GLuint oldIndex;
+   GLubyte *cdest = dest;
+
+   update_input_ptrs(ctx, oldIndex = elts[start++]);
+   vtx->emit( ctx, 1, cdest );
+   cdest += vtx->vertex_size;
+
+   for (; start < end; ++start) {
+      adjust_input_ptrs(ctx, elts[start] - oldIndex);
+      oldIndex = elts[start];
+      vtx->emit( ctx, 1, cdest);
+      cdest += vtx->vertex_size;
+   }
+
+   return (void *) cdest;
+}
+
 
 void _tnl_init_vertices( GLcontext *ctx, 
                        GLuint vb_size,
index 712311a1463e5797bbc921fd60a5186dbb4f9682..16071fb69550234db28b5d7908ca161090e7de69 100644 (file)
@@ -118,6 +118,12 @@ extern void *_tnl_emit_vertices_to_buffer( GLcontext *ctx,
                                           GLuint start,
                                           GLuint end,
                                           void *dest );
+extern void *_tnl_emit_indexed_vertices_to_buffer( GLcontext *ctx,
+                                                  const GLuint *elts,
+                                                  GLuint start,
+                                                  GLuint end,
+                                                  void *dest );
+
 
 extern void _tnl_build_vertices( GLcontext *ctx,
                                 GLuint start,