104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu/* 204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * Mesa 3-D graphics library 304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * 4877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * Copyright 2008 VMware, Inc. 504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * Copyright (C) 2010 LunarG Inc. 604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * 704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * Permission is hereby granted, free of charge, to any person obtaining a 804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * copy of this software and associated documentation files (the "Software"), 904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * to deal in the Software without restriction, including without limitation 1004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * and/or sell copies of the Software, and to permit persons to whom the 1204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * Software is furnished to do so, subject to the following conditions: 1304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * 1404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * The above copyright notice and this permission notice shall be included 1504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * in all copies or substantial portions of the Software. 1604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * 1704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * DEALINGS IN THE SOFTWARE. 2404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu */ 2504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 2604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wustatic void 2704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I WuFUNC(FUNC_VARS) 2804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu{ 2904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu unsigned first, incr; 3004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu LOCAL_VARS 3104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 3204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu /* 3304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * prim, start, count, and max_count_{simple,loop,fan} should have been 3404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * defined 3504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu */ 3604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu if (0) { 3704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu debug_printf("%s: prim 0x%x, start %d, count %d, max_count_simple %d, " 3804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu "max_count_loop %d, max_count_fan %d\n", 3904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu __FUNCTION__, prim, start, count, max_count_simple, 4004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu max_count_loop, max_count_fan); 4104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu } 4204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 4304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu draw_pt_split_prim(prim, &first, &incr); 4404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu /* sanitize primitive length */ 4504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu count = draw_pt_trim_count(count, first, incr); 4604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu if (count < first) 4704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu return; 4804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 49a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu /* try flushing the entire primitive */ 50a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu if (PRIMITIVE(start, count)) 51a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu return; 52a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu 5304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu /* must be able to at least flush two complete primitives */ 5404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu assert(max_count_simple >= first + incr && 5504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu max_count_loop >= first + incr && 5604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu max_count_fan >= first + incr); 5704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 5804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu /* no splitting required */ 5904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu if (count <= max_count_simple) { 6004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu SEGMENT_SIMPLE(0x0, start, count); 6104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu } 6204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu else { 6304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu const unsigned rollback = first - incr; 6404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu unsigned flags = DRAW_SPLIT_AFTER, seg_start = 0, seg_max; 6504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 6604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu /* 6704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * Both count and seg_max below are explicitly trimmed. Because 6804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * 6904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * seg_start = N * (seg_max - rollback) = N' * incr, 7004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * 7104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * we have 7204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * 7304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * remaining = count - seg_start = first + N'' * incr. 7404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * 7504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu * That is, remaining is implicitly trimmed. 7604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu */ 7704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu switch (prim) { 7804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu case PIPE_PRIM_POINTS: 7904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu case PIPE_PRIM_LINES: 8004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu case PIPE_PRIM_LINE_STRIP: 8104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu case PIPE_PRIM_TRIANGLES: 8204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu case PIPE_PRIM_TRIANGLE_STRIP: 8304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu case PIPE_PRIM_QUADS: 8404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu case PIPE_PRIM_QUAD_STRIP: 8504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu case PIPE_PRIM_LINES_ADJACENCY: 8604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu case PIPE_PRIM_LINE_STRIP_ADJACENCY: 8704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu case PIPE_PRIM_TRIANGLES_ADJACENCY: 8804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: 8904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu seg_max = 9004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu draw_pt_trim_count(MIN2(max_count_simple, count), first, incr); 9104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu if (prim == PIPE_PRIM_TRIANGLE_STRIP || 9204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu prim == PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY) { 9304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu /* make sure we flush even number of triangles at a time */ 9404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu if (seg_max < count && !(((seg_max - first) / incr) & 1)) 9504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu seg_max -= incr; 9604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu } 9704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 9804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu do { 9904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu const unsigned remaining = count - seg_start; 10004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 10104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu if (remaining > seg_max) { 10204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu SEGMENT_SIMPLE(flags, start + seg_start, seg_max); 10304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu seg_start += seg_max - rollback; 10404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 10504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu flags |= DRAW_SPLIT_BEFORE; 10604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu } 10704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu else { 10804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu flags &= ~DRAW_SPLIT_AFTER; 10904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 11004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu SEGMENT_SIMPLE(flags, start + seg_start, remaining); 11104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu seg_start += remaining; 11204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu } 11304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu } while (seg_start < count); 11404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu break; 11504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 11604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu case PIPE_PRIM_LINE_LOOP: 11704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu seg_max = 11804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu draw_pt_trim_count(MIN2(max_count_loop, count), first, incr); 11904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 12004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu do { 12104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu const unsigned remaining = count - seg_start; 12204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 12304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu if (remaining > seg_max) { 12404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu SEGMENT_LOOP(flags, start + seg_start, seg_max, start); 12504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu seg_start += seg_max - rollback; 12604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 12704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu flags |= DRAW_SPLIT_BEFORE; 12804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu } 12904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu else { 13004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu flags &= ~DRAW_SPLIT_AFTER; 13104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 13204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu SEGMENT_LOOP(flags, start + seg_start, remaining, start); 13304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu seg_start += remaining; 13404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu } 13504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu } while (seg_start < count); 13604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu break; 13704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 13804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu case PIPE_PRIM_TRIANGLE_FAN: 13904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu case PIPE_PRIM_POLYGON: 14004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu seg_max = 14104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu draw_pt_trim_count(MIN2(max_count_fan, count), first, incr); 14204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 14304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu do { 14404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu const unsigned remaining = count - seg_start; 14504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 14604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu if (remaining > seg_max) { 14704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu SEGMENT_FAN(flags, start + seg_start, seg_max, start); 14804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu seg_start += seg_max - rollback; 14904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 15004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu flags |= DRAW_SPLIT_BEFORE; 15104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu } 15204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu else { 15304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu flags &= ~DRAW_SPLIT_AFTER; 15404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 15504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu SEGMENT_FAN(flags, start + seg_start, remaining, start); 15604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu seg_start += remaining; 15704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu } 15804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu } while (seg_start < count); 15904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu break; 16004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 16104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu default: 16204bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu assert(0); 16304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu break; 16404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu } 16504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu } 16604bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu} 16704bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 16804bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#undef FUNC 16904bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#undef FUNC_VARS 17004bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#undef LOCAL_VARS 17104bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu 172a072f0e186522f9de2848989422ad0244f65c961Chia-I Wu#undef PRIMITIVE 17304bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#undef SEGMENT_SIMPLE 17404bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#undef SEGMENT_LOOP 17504bc530dbdbe5d004219c9100e35f5d56cfedd80Chia-I Wu#undef SEGMENT_FAN 176