1760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org/* 2760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * Mesa 3-D graphics library 3760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * Version: 7.9 4760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * 5760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 6760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * Copyright (C) 2010 LunarG Inc. 7760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * 8760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 9760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * copy of this software and associated documentation files (the "Software"), 10760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * to deal in the Software without restriction, including without limitation 11760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the 13760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * Software is furnished to do so, subject to the following conditions: 14760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * 15760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * The above copyright notice and this permission notice shall be included 16760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * in all copies or substantial portions of the Software. 17760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * 18760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * DEALINGS IN THE SOFTWARE. 25760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org */ 26760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 27760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.orgstatic void 28760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.orgFUNC(FUNC_VARS) 29760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org{ 30760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org unsigned first, incr; 31760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org LOCAL_VARS 32760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 33760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org /* 34760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * prim, start, count, and max_count_{simple,loop,fan} should have been 35760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * defined 36760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org */ 37760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org if (0) { 38760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org debug_printf("%s: prim 0x%x, start %d, count %d, max_count_simple %d, " 39760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org "max_count_loop %d, max_count_fan %d\n", 40760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org __FUNCTION__, prim, start, count, max_count_simple, 41760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org max_count_loop, max_count_fan); 42760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } 43760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 44760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org draw_pt_split_prim(prim, &first, &incr); 45760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org /* sanitize primitive length */ 46760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org count = draw_pt_trim_count(count, first, incr); 47760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org if (count < first) 48760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org return; 49760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 50760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org /* try flushing the entire primitive */ 51760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org if (PRIMITIVE(start, count)) 52760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org return; 53760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 54760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org /* must be able to at least flush two complete primitives */ 55760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org assert(max_count_simple >= first + incr && 56760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org max_count_loop >= first + incr && 57760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org max_count_fan >= first + incr); 58760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 59760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org /* no splitting required */ 60760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org if (count <= max_count_simple) { 61760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org SEGMENT_SIMPLE(0x0, start, count); 62760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } 63760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org else { 64760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org const unsigned rollback = first - incr; 65760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org unsigned flags = DRAW_SPLIT_AFTER, seg_start = 0, seg_max; 66760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 67760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org /* 68760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * Both count and seg_max below are explicitly trimmed. Because 69760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * 70760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * seg_start = N * (seg_max - rollback) = N' * incr, 71760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * 72760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * we have 73760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * 74760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * remaining = count - seg_start = first + N'' * incr. 75760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * 76760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org * That is, remaining is implicitly trimmed. 77760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org */ 78760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org switch (prim) { 79760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_POINTS: 80760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_LINES: 81760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_LINE_STRIP: 82760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_TRIANGLES: 83760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_TRIANGLE_STRIP: 84760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_QUADS: 85760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_QUAD_STRIP: 86760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_LINES_ADJACENCY: 87760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_LINE_STRIP_ADJACENCY: 88760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_TRIANGLES_ADJACENCY: 89760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: 90760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org seg_max = 91760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org draw_pt_trim_count(MIN2(max_count_simple, count), first, incr); 92760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org if (prim == PIPE_PRIM_TRIANGLE_STRIP || 93760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org prim == PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY) { 94760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org /* make sure we flush even number of triangles at a time */ 95760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org if (seg_max < count && !(((seg_max - first) / incr) & 1)) 96760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org seg_max -= incr; 97760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } 98760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 99760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org do { 100760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org const unsigned remaining = count - seg_start; 101760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 102760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org if (remaining > seg_max) { 103760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org SEGMENT_SIMPLE(flags, start + seg_start, seg_max); 104760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org seg_start += seg_max - rollback; 105760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 106760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org flags |= DRAW_SPLIT_BEFORE; 107760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } 108760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org else { 109760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org flags &= ~DRAW_SPLIT_AFTER; 110760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 111760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org SEGMENT_SIMPLE(flags, start + seg_start, remaining); 112760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org seg_start += remaining; 113760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } 114760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } while (seg_start < count); 115760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org break; 116760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 117760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_LINE_LOOP: 118760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org seg_max = 119760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org draw_pt_trim_count(MIN2(max_count_loop, count), first, incr); 120760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 121760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org do { 122760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org const unsigned remaining = count - seg_start; 123760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 124760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org if (remaining > seg_max) { 125760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org SEGMENT_LOOP(flags, start + seg_start, seg_max, start); 126760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org seg_start += seg_max - rollback; 127760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 128760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org flags |= DRAW_SPLIT_BEFORE; 129760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } 130760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org else { 131760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org flags &= ~DRAW_SPLIT_AFTER; 132760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 133760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org SEGMENT_LOOP(flags, start + seg_start, remaining, start); 134760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org seg_start += remaining; 135760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } 136760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } while (seg_start < count); 137760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org break; 138760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 139760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_TRIANGLE_FAN: 140760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org case PIPE_PRIM_POLYGON: 141760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org seg_max = 142760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org draw_pt_trim_count(MIN2(max_count_fan, count), first, incr); 143760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 144760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org do { 145760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org const unsigned remaining = count - seg_start; 146760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 147760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org if (remaining > seg_max) { 148760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org SEGMENT_FAN(flags, start + seg_start, seg_max, start); 149760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org seg_start += seg_max - rollback; 150760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 151760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org flags |= DRAW_SPLIT_BEFORE; 152760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } 153760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org else { 154760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org flags &= ~DRAW_SPLIT_AFTER; 155760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 156760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org SEGMENT_FAN(flags, start + seg_start, remaining, start); 157760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org seg_start += remaining; 158760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } 159760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } while (seg_start < count); 160760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org break; 161760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 162760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org default: 163760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org assert(0); 164760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org break; 165760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } 166760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org } 167760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org} 168760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 169760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#undef FUNC 170760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#undef FUNC_VARS 171760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#undef LOCAL_VARS 172760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org 173760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#undef PRIMITIVE 174760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#undef SEGMENT_SIMPLE 175760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#undef SEGMENT_LOOP 176760fd893ba809a7a5daa25c2749ff502f7186e83kbr@chromium.org#undef SEGMENT_FAN 177