1bf215546Sopenharmony_ci/* Originally written by Ben Skeggs for the nv50 driver*/ 2bf215546Sopenharmony_ci 3bf215546Sopenharmony_ci#ifndef U_SPLIT_PRIM_H 4bf215546Sopenharmony_ci#define U_SPLIT_PRIM_H 5bf215546Sopenharmony_ci 6bf215546Sopenharmony_ci#include "pipe/p_defines.h" 7bf215546Sopenharmony_ci#include "pipe/p_compiler.h" 8bf215546Sopenharmony_ci 9bf215546Sopenharmony_ci#include "util/u_debug.h" 10bf215546Sopenharmony_ci 11bf215546Sopenharmony_cistruct util_split_prim { 12bf215546Sopenharmony_ci void *priv; 13bf215546Sopenharmony_ci void (*emit)(void *priv, unsigned start, unsigned count); 14bf215546Sopenharmony_ci void (*edge)(void *priv, boolean enabled); 15bf215546Sopenharmony_ci 16bf215546Sopenharmony_ci unsigned mode; 17bf215546Sopenharmony_ci unsigned start; 18bf215546Sopenharmony_ci unsigned p_start; 19bf215546Sopenharmony_ci unsigned p_end; 20bf215546Sopenharmony_ci 21bf215546Sopenharmony_ci uint repeat_first:1; 22bf215546Sopenharmony_ci uint close_first:1; 23bf215546Sopenharmony_ci uint edgeflag_off:1; 24bf215546Sopenharmony_ci}; 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_cistatic inline void 27bf215546Sopenharmony_ciutil_split_prim_init(struct util_split_prim *s, 28bf215546Sopenharmony_ci unsigned mode, unsigned start, unsigned count) 29bf215546Sopenharmony_ci{ 30bf215546Sopenharmony_ci if (mode == PIPE_PRIM_LINE_LOOP) { 31bf215546Sopenharmony_ci s->mode = PIPE_PRIM_LINE_STRIP; 32bf215546Sopenharmony_ci s->close_first = 1; 33bf215546Sopenharmony_ci } else { 34bf215546Sopenharmony_ci s->mode = mode; 35bf215546Sopenharmony_ci s->close_first = 0; 36bf215546Sopenharmony_ci } 37bf215546Sopenharmony_ci s->start = start; 38bf215546Sopenharmony_ci s->p_start = start; 39bf215546Sopenharmony_ci s->p_end = start + count; 40bf215546Sopenharmony_ci s->edgeflag_off = 0; 41bf215546Sopenharmony_ci s->repeat_first = 0; 42bf215546Sopenharmony_ci} 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_cistatic inline boolean 45bf215546Sopenharmony_ciutil_split_prim_next(struct util_split_prim *s, unsigned max_verts) 46bf215546Sopenharmony_ci{ 47bf215546Sopenharmony_ci int repeat = 0; 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci if (s->repeat_first) { 50bf215546Sopenharmony_ci s->emit(s->priv, s->start, 1); 51bf215546Sopenharmony_ci max_verts--; 52bf215546Sopenharmony_ci if (s->edgeflag_off) { 53bf215546Sopenharmony_ci s->edge(s->priv, TRUE); 54bf215546Sopenharmony_ci s->edgeflag_off = FALSE; 55bf215546Sopenharmony_ci } 56bf215546Sopenharmony_ci } 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci if ((s->p_end - s->p_start) + s->close_first <= max_verts) { 59bf215546Sopenharmony_ci s->emit(s->priv, s->p_start, s->p_end - s->p_start); 60bf215546Sopenharmony_ci if (s->close_first) 61bf215546Sopenharmony_ci s->emit(s->priv, s->start, 1); 62bf215546Sopenharmony_ci return TRUE; 63bf215546Sopenharmony_ci } 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci switch (s->mode) { 66bf215546Sopenharmony_ci case PIPE_PRIM_LINES: 67bf215546Sopenharmony_ci max_verts &= ~1; 68bf215546Sopenharmony_ci break; 69bf215546Sopenharmony_ci case PIPE_PRIM_LINE_STRIP: 70bf215546Sopenharmony_ci repeat = 1; 71bf215546Sopenharmony_ci break; 72bf215546Sopenharmony_ci case PIPE_PRIM_POLYGON: 73bf215546Sopenharmony_ci max_verts--; 74bf215546Sopenharmony_ci s->emit(s->priv, s->p_start, max_verts); 75bf215546Sopenharmony_ci s->edge(s->priv, FALSE); 76bf215546Sopenharmony_ci s->emit(s->priv, s->p_start + max_verts, 1); 77bf215546Sopenharmony_ci s->p_start += max_verts; 78bf215546Sopenharmony_ci s->repeat_first = TRUE; 79bf215546Sopenharmony_ci s->edgeflag_off = TRUE; 80bf215546Sopenharmony_ci return FALSE; 81bf215546Sopenharmony_ci case PIPE_PRIM_TRIANGLES: 82bf215546Sopenharmony_ci max_verts = max_verts - (max_verts % 3); 83bf215546Sopenharmony_ci break; 84bf215546Sopenharmony_ci case PIPE_PRIM_TRIANGLE_STRIP: 85bf215546Sopenharmony_ci /* to ensure winding stays correct, always split 86bf215546Sopenharmony_ci * on an even number of generated triangles 87bf215546Sopenharmony_ci */ 88bf215546Sopenharmony_ci max_verts = max_verts & ~1; 89bf215546Sopenharmony_ci repeat = 2; 90bf215546Sopenharmony_ci break; 91bf215546Sopenharmony_ci case PIPE_PRIM_TRIANGLE_FAN: 92bf215546Sopenharmony_ci s->repeat_first = TRUE; 93bf215546Sopenharmony_ci repeat = 1; 94bf215546Sopenharmony_ci break; 95bf215546Sopenharmony_ci case PIPE_PRIM_QUADS: 96bf215546Sopenharmony_ci max_verts &= ~3; 97bf215546Sopenharmony_ci break; 98bf215546Sopenharmony_ci case PIPE_PRIM_QUAD_STRIP: 99bf215546Sopenharmony_ci max_verts &= ~1; 100bf215546Sopenharmony_ci repeat = 2; 101bf215546Sopenharmony_ci break; 102bf215546Sopenharmony_ci case PIPE_PRIM_POINTS: 103bf215546Sopenharmony_ci break; 104bf215546Sopenharmony_ci default: 105bf215546Sopenharmony_ci /* TODO: implement adjacency primitives */ 106bf215546Sopenharmony_ci assert(0); 107bf215546Sopenharmony_ci } 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci s->emit (s->priv, s->p_start, max_verts); 110bf215546Sopenharmony_ci s->p_start += (max_verts - repeat); 111bf215546Sopenharmony_ci return FALSE; 112bf215546Sopenharmony_ci} 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci#endif /* U_SPLIT_PRIM_H */ 115