convert vbo->draw_prims() to pipe->draw_arrays(): works in very limited cases, disabl...
authorBrian <brian.paul@tungstengraphics.com>
Thu, 16 Aug 2007 01:00:06 +0000 (19:00 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Thu, 16 Aug 2007 01:04:44 +0000 (19:04 -0600)
src/mesa/state_tracker/st_draw.c

index 002565a658dfe3140293416f73261bd0ee4b40fa..0b134322560617d6771f3b79e3808cd6679bbb91 100644 (file)
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 
+#include "vbo/vbo_context.h"
+
+/*
+ * Enabling this causes the VBO module to call draw_vbo() below,
+ * bypassing the T&L module.  This only works with VBO-based demos,
+ * such as progs/test/bufferobj.c
+ */
+#define USE_NEW_DRAW 0
+
 
 /*
  * TNL stage which feeds into the above.
@@ -95,6 +104,31 @@ static const struct tnl_pipeline_stage *st_pipeline[] = {
 
 
 
+static GLuint
+pipe_vertex_format(GLenum format, GLuint size)
+{
+   static const GLuint float_fmts[4] = {
+      PIPE_FORMAT_R32_FLOAT,
+      PIPE_FORMAT_R32G32_FLOAT,
+      PIPE_FORMAT_R32G32B32_FLOAT,
+      PIPE_FORMAT_R32G32B32A32_FLOAT,
+   };
+
+   assert(format >= GL_BYTE);
+   assert(format <= GL_DOUBLE);
+   assert(size >= 1);
+   assert(size <= 4);
+
+   switch (format) {
+   case GL_FLOAT:
+      return float_fmts[size - 1];
+   default:
+      assert(0);
+   }
+}
+
+
+
 /**
  * This function gets plugged into the VBO module and is called when
  * we have something to render.
@@ -110,35 +144,48 @@ draw_vbo(GLcontext *ctx,
          GLuint max_index)
 {
    struct pipe_context *pipe = ctx->st->pipe;
-   GLuint attr;
+   GLuint attr, i;
 
    /* tell pipe about the vertex array element/attributes */
    for (attr = 0; attr < 16; attr++) {
       struct gl_buffer_object *bufobj = arrays[attr]->BufferObj;
+      struct pipe_vertex_buffer vbuffer;
+      struct pipe_vertex_element velement;
+
       if (bufobj && bufobj->Name) {
          struct st_buffer_object *stobj = st_buffer_object(bufobj);
-         struct pipe_buffer_handle *buffer = stobj->buffer;
-         GLenum type = arrays[attr]->Type;
-         GLint  size = arrays[attr]->Size;
-         struct pipe_vertex_buffer vbuffer;
-         struct pipe_vertex_element velement;
 
-         vbuffer.pitch = 0;
+         assert(stobj->buffer);
+
+         vbuffer.pitch = arrays[attr]->StrideB; /* in bytes */
          vbuffer.max_index = 0;
-         vbuffer.buffer = NULL;
+         vbuffer.buffer = stobj->buffer;
          vbuffer.buffer_offset = 0;
 
-         velement.src_offset = 0;
+         /* Recall that for VBOs, the gl_client_array->Ptr field is
+          * really an offset from the start of the VBO, not a pointer.
+          */
+         velement.src_offset = (unsigned) arrays[attr]->Ptr;
          velement.vertex_buffer_index = attr;
          velement.dst_offset = 0;
-         velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+         velement.src_format = pipe_vertex_format(arrays[attr]->Type,
+                                                  arrays[attr]->Size);
+      }
+      else {
+         /* vertex attribute data is not an a real buffer! */
+         /* XXX we'll want to handle that someday... */
 
-         pipe->set_vertex_buffer(pipe, attr, &vbuffer);
-         pipe->set_vertex_element(pipe, attr, &velement);
+         vbuffer.buffer = NULL;
       }
+
+      pipe->set_vertex_buffer(pipe, attr, &vbuffer);
+      pipe->set_vertex_element(pipe, attr, &velement);
    }
 
    /* do actual drawing */
+   for (i = 0; i < nr_prims; i++) {
+      pipe->draw_arrays(pipe, prims[i].mode, prims[i].start, prims[i].count);
+   }
 }
 
 
@@ -151,8 +198,18 @@ void st_init_draw( struct st_context *st )
 {
    GLcontext *ctx = st->ctx;
 
+#if USE_NEW_DRAW
+   struct vbo_context *vbo = (struct vbo_context *) ctx->swtnl_im;
+
+   assert(vbo);
+   assert(vbo->draw_prims);
+   vbo->draw_prims = draw_vbo;
+
+#else
    _tnl_destroy_pipeline( ctx );
    _tnl_install_pipeline( ctx, st_pipeline );
+#endif
+
 }