1760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org/* Originally written by Ben Skeggs for the nv50 driver*/ 2760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 3760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#ifndef U_SPLIT_PRIM_H 4760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#define U_SPLIT_PRIM_H 5760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 6760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#include "pipe/p_defines.h" 7760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#include "pipe/p_compiler.h" 8760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 9760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#include "util/u_debug.h" 10760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 11760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.orgstruct util_split_prim { 12760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org void *priv; 13760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org void (*emit)(void *priv, unsigned start, unsigned count); 14760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org void (*edge)(void *priv, boolean enabled); 15760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 16760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org unsigned mode; 17760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org unsigned start; 18760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org unsigned p_start; 19760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org unsigned p_end; 20760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 21760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org uint repeat_first:1; 22760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org uint close_first:1; 23760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org uint edgeflag_off:1; 24760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org}; 25760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 26760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.orgstatic INLINE void 27760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.orgutil_split_prim_init(struct util_split_prim *s, 28760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org unsigned mode, unsigned start, unsigned count) 29760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org{ 30760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org if (mode == PIPE_PRIM_LINE_LOOP) { 31760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->mode = PIPE_PRIM_LINE_STRIP; 32760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->close_first = 1; 33760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } else { 34760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->mode = mode; 35760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->close_first = 0; 36760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } 37760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->start = start; 38760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->p_start = start; 39760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->p_end = start + count; 40760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->edgeflag_off = 0; 41760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->repeat_first = 0; 42760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org} 43760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 44760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.orgstatic INLINE boolean 45760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.orgutil_split_prim_next(struct util_split_prim *s, unsigned max_verts) 46760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org{ 47760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org int repeat = 0; 48760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 49760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org if (s->repeat_first) { 50760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->emit(s->priv, s->start, 1); 51760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org max_verts--; 52760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org if (s->edgeflag_off) { 53760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->edge(s->priv, TRUE); 54760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->edgeflag_off = FALSE; 55760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } 56760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } 57760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 58760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org if ((s->p_end - s->p_start) + s->close_first <= max_verts) { 59760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->emit(s->priv, s->p_start, s->p_end - s->p_start); 60760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org if (s->close_first) 61760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->emit(s->priv, s->start, 1); 62760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org return TRUE; 63760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } 64760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 65760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org switch (s->mode) { 66760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_LINES: 67760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org max_verts &= ~1; 68760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org break; 69760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_LINE_STRIP: 70760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org repeat = 1; 71760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org break; 72760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_POLYGON: 73760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org max_verts--; 74760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->emit(s->priv, s->p_start, max_verts); 75760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->edge(s->priv, FALSE); 76760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->emit(s->priv, s->p_start + max_verts, 1); 77760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->p_start += max_verts; 78760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->repeat_first = TRUE; 79760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->edgeflag_off = TRUE; 80760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org return FALSE; 81760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_TRIANGLES: 82760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org max_verts = max_verts - (max_verts % 3); 83760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org break; 84760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_TRIANGLE_STRIP: 85760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org /* to ensure winding stays correct, always split 86760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * on an even number of generated triangles 87760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org */ 88760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org max_verts = max_verts & ~1; 89760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org repeat = 2; 90760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org break; 91760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_TRIANGLE_FAN: 92760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->repeat_first = TRUE; 93760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org repeat = 1; 94760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org break; 95760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_QUADS: 96760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org max_verts &= ~3; 97760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org break; 98760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_QUAD_STRIP: 99760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org max_verts &= ~1; 100760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org repeat = 2; 101760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org break; 102760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_POINTS: 103760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org break; 104760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org default: 105760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org /* TODO: implement adjacency primitives */ 106760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org assert(0); 107760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } 108760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 109760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->emit (s->priv, s->p_start, max_verts); 110760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org s->p_start += (max_verts - repeat); 111760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org return FALSE; 112760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org} 113760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 114760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#endif /* U_SPLIT_PRIM_H */ 115