auxiliary: move Ben Skeggs' primitive splitter to common code
authorLuca Barbieri <luca@luca-barbieri.com>
Wed, 11 Aug 2010 08:46:12 +0000 (10:46 +0200)
committerLuca Barbieri <luca@luca-barbieri.com>
Wed, 11 Aug 2010 09:08:46 +0000 (11:08 +0200)
This is a simple framework that handles splitting primitives in an
abstract way.

The user has to specify the primitive start, start index and count.

Then, it can ask the primitive splitter to "draw" a chunk of the
primitive, staying under a given vertex/index budget.

The primitive splitter will then call user-supplied functions to
emit a range of vertices/indices, as well as switch the edgeflag
on or off.

This is particularly useful for hardware that either has limits
on the vertex count field, or where vertices are pushed on a FIFO
or temporary buffer of limited size.

Note that unlike other splitters, it does not manipulate data in
any way, and merely asks a callback to do so, in vertex intervals.

src/gallium/auxiliary/util/u_split_prim.h [new file with mode: 0644]
src/gallium/drivers/nouveau/nouveau_util.h
src/gallium/drivers/nv50/nv50_push.c
src/gallium/drivers/nv50/nv50_vbo.c

diff --git a/src/gallium/auxiliary/util/u_split_prim.h b/src/gallium/auxiliary/util/u_split_prim.h
new file mode 100644 (file)
index 0000000..3c438da
--- /dev/null
@@ -0,0 +1,102 @@
+/* Originally written by Ben Skeggs for the nv50 driver*/
+#include <pipe/p_defines.h>
+
+struct u_split_prim {
+   void *priv;
+   void (*emit)(void *priv, unsigned start, unsigned count);
+   void (*edge)(void *priv, boolean enabled);
+
+   unsigned mode;
+   unsigned start;
+   unsigned p_start;
+   unsigned p_end;
+
+   uint repeat_first:1;
+   uint close_first:1;
+   uint edgeflag_off:1;
+};
+
+static INLINE void
+u_split_prim_init(struct u_split_prim *s,
+                  unsigned mode, unsigned start, unsigned count)
+{
+   if (mode == PIPE_PRIM_LINE_LOOP) {
+      s->mode = PIPE_PRIM_LINE_STRIP;
+      s->close_first = 1;
+   } else {
+      s->mode = mode;
+      s->close_first = 0;
+   }
+   s->start = start;
+   s->p_start = start;
+   s->p_end = start + count;
+   s->edgeflag_off = 0;
+   s->repeat_first = 0;
+}
+
+static INLINE boolean
+u_split_prim_next(struct u_split_prim *s, unsigned max_verts)
+{
+   int repeat = 0;
+
+   if (s->repeat_first) {
+      s->emit(s->priv, s->start, 1);
+      max_verts--;
+      if (s->edgeflag_off) {
+         s->edge(s->priv, TRUE);
+         s->edgeflag_off = FALSE;
+      }
+   }
+
+   if (s->p_start + s->close_first + max_verts >= s->p_end) {
+      s->emit(s->priv, s->p_start, s->p_end - s->p_start);
+      if (s->close_first)
+         s->emit(s->priv, s->start, 1);
+      return TRUE;
+   }
+
+   switch (s->mode) {
+   case PIPE_PRIM_LINES:
+      max_verts &= ~1;
+      break;
+   case PIPE_PRIM_LINE_STRIP:
+      repeat = 1;
+      break;
+   case PIPE_PRIM_POLYGON:
+      max_verts--;
+      s->emit(s->priv, s->p_start, max_verts);
+      s->edge(s->priv, FALSE);
+      s->emit(s->priv, s->p_start + max_verts, 1);
+      s->p_start += max_verts;
+      s->repeat_first = TRUE;
+      s->edgeflag_off = TRUE;
+      return FALSE;
+   case PIPE_PRIM_TRIANGLES:
+      max_verts = max_verts - (max_verts % 3);
+      break;
+   case PIPE_PRIM_TRIANGLE_STRIP:
+      /* to ensure winding stays correct, always split
+       * on an even number of generated triangles
+       */
+      max_verts = max_verts & ~1;
+      repeat = 2;
+      break;
+   case PIPE_PRIM_TRIANGLE_FAN:
+      s->repeat_first = TRUE;
+      repeat = 1;
+      break;
+   case PIPE_PRIM_QUADS:
+      max_verts &= ~3;
+      break;
+   case PIPE_PRIM_QUAD_STRIP:
+      max_verts &= ~1;
+      repeat = 2;
+      break;
+   default:
+      break;
+   }
+
+   s->emit (s->priv, s->p_start, max_verts);
+   s->p_start += (max_verts - repeat);
+   return FALSE;
+}
index a5e8537533e7d97e18ef5be296a3df0a41814a34..b165f7a611a4b922cd21612d0018a16cefe754f1 100644 (file)
@@ -88,104 +88,4 @@ static INLINE unsigned log2i(unsigned i)
        return r;
 }
 
-struct u_split_prim {
-   void *priv;
-   void (*emit)(void *priv, unsigned start, unsigned count);
-   void (*edge)(void *priv, boolean enabled);
-
-   unsigned mode;
-   unsigned start;
-   unsigned p_start;
-   unsigned p_end;
-
-   uint repeat_first:1;
-   uint close_first:1;
-   uint edgeflag_off:1;
-};
-
-static INLINE void
-u_split_prim_init(struct u_split_prim *s,
-                  unsigned mode, unsigned start, unsigned count)
-{
-   if (mode == PIPE_PRIM_LINE_LOOP) {
-      s->mode = PIPE_PRIM_LINE_STRIP;
-      s->close_first = 1;
-   } else {
-      s->mode = mode;
-      s->close_first = 0;
-   }
-   s->start = start;
-   s->p_start = start;
-   s->p_end = start + count;
-   s->edgeflag_off = 0;
-   s->repeat_first = 0;
-}
-
-static INLINE boolean
-u_split_prim_next(struct u_split_prim *s, unsigned max_verts)
-{
-   int repeat = 0;
-
-   if (s->repeat_first) {
-      s->emit(s->priv, s->start, 1);
-      max_verts--;
-      if (s->edgeflag_off) {
-         s->edge(s->priv, TRUE);
-         s->edgeflag_off = FALSE;
-      }
-   }
-
-   if (s->p_start + s->close_first + max_verts >= s->p_end) {
-      s->emit(s->priv, s->p_start, s->p_end - s->p_start);
-      if (s->close_first)
-         s->emit(s->priv, s->start, 1);
-      return TRUE;
-   }
-
-   switch (s->mode) {
-   case PIPE_PRIM_LINES:
-      max_verts &= ~1;
-      break;
-   case PIPE_PRIM_LINE_STRIP:
-      repeat = 1;
-      break;
-   case PIPE_PRIM_POLYGON:
-      max_verts--;
-      s->emit(s->priv, s->p_start, max_verts);
-      s->edge(s->priv, FALSE);
-      s->emit(s->priv, s->p_start + max_verts, 1);
-      s->p_start += max_verts;
-      s->repeat_first = TRUE;
-      s->edgeflag_off = TRUE;
-      return FALSE;
-   case PIPE_PRIM_TRIANGLES:
-      max_verts = max_verts - (max_verts % 3);
-      break;
-   case PIPE_PRIM_TRIANGLE_STRIP:
-      /* to ensure winding stays correct, always split
-       * on an even number of generated triangles
-       */
-      max_verts = max_verts & ~1;
-      repeat = 2;
-      break;
-   case PIPE_PRIM_TRIANGLE_FAN:
-      s->repeat_first = TRUE;
-      repeat = 1;
-      break;
-   case PIPE_PRIM_QUADS:
-      max_verts &= ~3;
-      break;
-   case PIPE_PRIM_QUAD_STRIP:
-      max_verts &= ~1;
-      repeat = 2;
-      break;
-   default:
-      break;
-   }
-
-   s->emit (s->priv, s->p_start, max_verts);
-   s->p_start += (max_verts - repeat);
-   return FALSE;
-}
-
 #endif
index c3ac804146267a08eb75a6cdbc6aaec07fb9dad2..ee87144dcf10a8d11e0a0843d38a6f2e54dab559 100644 (file)
@@ -2,8 +2,8 @@
 #include "pipe/p_state.h"
 #include "util/u_inlines.h"
 #include "util/u_format.h"
+#include "util/u_split_prim.h"
 
-#include "nouveau/nouveau_util.h"
 #include "nv50_context.h"
 #include "nv50_resource.h"
 
index e7f8fe33edf5b7d2723274c8e3945f7c6044be14..0937668b84576339b05aa4f90d17aeb13690b54a 100644 (file)
@@ -24,8 +24,8 @@
 #include "pipe/p_state.h"
 #include "util/u_inlines.h"
 #include "util/u_format.h"
+#include "util/u_split_prim.h"
 
-#include "nouveau/nouveau_util.h"
 #include "nv50_context.h"
 #include "nv50_resource.h"