summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nouveau/nouveau_util.h
diff options
context:
space:
mode:
authorMichal Krol <[email protected]>2010-03-10 15:49:30 +0100
committerMichal Krol <[email protected]>2010-03-10 15:49:30 +0100
commit3ce4375912c8ea488460e593e07c5bb15b92dca9 (patch)
tree1011fa439bd829fd46a44fd99478135848800e73 /src/gallium/drivers/nouveau/nouveau_util.h
parentf59f28093ea827bd234d8e1a36bdd56a9fce5f09 (diff)
parent9b348d0ed125a22be3f318ac60cef6f201edfdab (diff)
Merge branch 'master' into gallium-sampler-view
Conflicts: src/gallium/auxiliary/Makefile src/gallium/auxiliary/SConscript src/gallium/auxiliary/tgsi/tgsi_exec.c src/gallium/auxiliary/util/u_blitter.c src/gallium/drivers/i915/i915_context.h src/gallium/drivers/i965/brw_context.h src/gallium/drivers/llvmpipe/lp_context.h src/gallium/drivers/nv50/nv50_context.h src/gallium/drivers/nv50/nv50_state_validate.c src/gallium/drivers/nv50/nv50_tex.c src/gallium/drivers/r300/r300_blit.c src/gallium/drivers/r300/r300_context.h src/gallium/drivers/r300/r300_emit.c src/gallium/drivers/r300/r300_state.c src/gallium/drivers/softpipe/sp_context.h src/gallium/drivers/svga/svga_context.h src/gallium/drivers/svga/svga_pipe_sampler.c
Diffstat (limited to 'src/gallium/drivers/nouveau/nouveau_util.h')
-rw-r--r--src/gallium/drivers/nouveau/nouveau_util.h100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/gallium/drivers/nouveau/nouveau_util.h b/src/gallium/drivers/nouveau/nouveau_util.h
index a10114beab9..7f16e31c3f0 100644
--- a/src/gallium/drivers/nouveau/nouveau_util.h
+++ b/src/gallium/drivers/nouveau/nouveau_util.h
@@ -88,4 +88,104 @@ 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;
+
+ int repeat_first:1;
+ int close_first:1;
+ int 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