gallium: initial edgeflags code
authorBrian Paul <brian.paul@tungstengraphics.com>
Thu, 24 Apr 2008 22:01:18 +0000 (16:01 -0600)
committerBrian Paul <brian.paul@tungstengraphics.com>
Thu, 24 Apr 2008 22:01:18 +0000 (16:01 -0600)
src/mesa/state_tracker/st_draw.c

index befcb96bd89530b4fc98626d8b7f3c950f3313ef..097166f4446af98a01f047027a72525d9e8f7b00 100644 (file)
@@ -190,6 +190,57 @@ pipe_vertex_format(GLenum type, GLuint size, GLboolean normalized)
 }
 
 
+/*
+ * If edge flags are needed, setup an bitvector of flags and call
+ * pipe->set_edgeflags().
+ * XXX memleak: need to free the returned pointer at some point
+ */
+static void *
+setup_edgeflags(GLcontext *ctx, GLenum primMode, GLint start, GLint count,
+                const struct gl_client_array *array)
+{
+   struct pipe_context *pipe = ctx->st->pipe;
+
+   if ((primMode == GL_TRIANGLES ||
+        primMode == GL_QUADS ||
+        primMode == GL_POLYGON) &&
+       (ctx->Polygon.FrontMode != GL_FILL ||
+        ctx->Polygon.BackMode != GL_FILL)) {
+      /* need edge flags */
+      GLuint i;
+      unsigned *vec = (unsigned *) calloc(sizeof(unsigned), (count + 31) / 32);
+      struct st_buffer_object *stobj = st_buffer_object(array->BufferObj);
+      ubyte *map;
+
+      if (!vec)
+         return NULL;
+
+      map = pipe->winsys->buffer_map(pipe->winsys, stobj->buffer,
+                                     PIPE_BUFFER_USAGE_CPU_READ);
+      map = ADD_POINTERS(map, array->Ptr);
+
+      for (i = 0; i < count; i++) {
+         if (*((float *) map))
+            vec[i/32] |= 1 << (i % 32);
+
+         map += array->StrideB;
+      }
+
+      pipe->winsys->buffer_unmap(pipe->winsys, stobj->buffer);
+
+      pipe->set_edgeflags(pipe, vec);
+
+      return vec;
+   }
+   else {
+      /* edge flags not needed */
+      pipe->set_edgeflags(pipe, NULL);
+      return NULL;
+   }
+}
+
+
+
 /**
  * This function gets plugged into the VBO module and is called when
  * we have something to render.
@@ -277,7 +328,6 @@ st_draw_vbo(GLcontext *ctx,
    pipe->set_vertex_buffers(pipe, vp->num_inputs, vbuffer);
    pipe->set_vertex_elements(pipe, vp->num_inputs, velements);
 
-
    /* do actual drawing */
    if (ib) {
       /* indexed primitive */
@@ -317,6 +367,10 @@ st_draw_vbo(GLcontext *ctx,
 
       /* draw */
       for (i = 0; i < nr_prims; i++) {
+         setup_edgeflags(ctx, prims[i].mode,
+                         prims[i].start + indexOffset, prims[i].count,
+                         arrays[VERT_ATTRIB_EDGEFLAG]);
+
          pipe->draw_elements(pipe, indexBuf, indexSize,
                              prims[i].mode,
                              prims[i].start + indexOffset, prims[i].count);
@@ -328,6 +382,10 @@ st_draw_vbo(GLcontext *ctx,
       /* non-indexed */
       GLuint i;
       for (i = 0; i < nr_prims; i++) {
+         setup_edgeflags(ctx, prims[i].mode,
+                         prims[i].start, prims[i].count,
+                         arrays[VERT_ATTRIB_EDGEFLAG]);
+
          pipe->draw_arrays(pipe, prims[i].mode, prims[i].start, prims[i].count);
       }
    }