Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
  5.  * Copyright (C) 2010 LunarG Inc.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included
  15.  * in all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  23.  * DEALINGS IN THE SOFTWARE.
  24.  */
  25.  
  26. static void
  27. FUNC(FUNC_VARS)
  28. {
  29.    unsigned first, incr;
  30.    LOCAL_VARS
  31.  
  32.    /*
  33.     * prim, start, count, and max_count_{simple,loop,fan} should have been
  34.     * defined
  35.     */
  36.    if (0) {
  37.       debug_printf("%s: prim 0x%x, start %d, count %d, max_count_simple %d, "
  38.                    "max_count_loop %d, max_count_fan %d\n",
  39.                    __FUNCTION__, prim, start, count, max_count_simple,
  40.                    max_count_loop, max_count_fan);
  41.    }
  42.  
  43.    draw_pt_split_prim(prim, &first, &incr);
  44.    /* sanitize primitive length */
  45.    count = draw_pt_trim_count(count, first, incr);
  46.    if (count < first)
  47.       return;
  48.  
  49.    /* try flushing the entire primitive */
  50.    if (PRIMITIVE(start, count))
  51.       return;
  52.  
  53.    /* must be able to at least flush two complete primitives */
  54.    assert(max_count_simple >= first + incr &&
  55.           max_count_loop >= first + incr &&
  56.           max_count_fan >= first + incr);
  57.  
  58.    /* no splitting required */
  59.    if (count <= max_count_simple) {
  60.       SEGMENT_SIMPLE(0x0, start, count);
  61.    }
  62.    else {
  63.       const unsigned rollback = first - incr;
  64.       unsigned flags = DRAW_SPLIT_AFTER, seg_start = 0, seg_max;
  65.  
  66.       /*
  67.        * Both count and seg_max below are explicitly trimmed.  Because
  68.        *
  69.        *   seg_start = N * (seg_max - rollback) = N' * incr,
  70.        *
  71.        * we have
  72.        *
  73.        *   remaining = count - seg_start = first + N'' * incr.
  74.        *
  75.        * That is, remaining is implicitly trimmed.
  76.        */
  77.       switch (prim) {
  78.       case PIPE_PRIM_POINTS:
  79.       case PIPE_PRIM_LINES:
  80.       case PIPE_PRIM_LINE_STRIP:
  81.       case PIPE_PRIM_TRIANGLES:
  82.       case PIPE_PRIM_TRIANGLE_STRIP:
  83.       case PIPE_PRIM_QUADS:
  84.       case PIPE_PRIM_QUAD_STRIP:
  85.       case PIPE_PRIM_LINES_ADJACENCY:
  86.       case PIPE_PRIM_LINE_STRIP_ADJACENCY:
  87.       case PIPE_PRIM_TRIANGLES_ADJACENCY:
  88.       case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
  89.          seg_max =
  90.             draw_pt_trim_count(MIN2(max_count_simple, count), first, incr);
  91.          if (prim == PIPE_PRIM_TRIANGLE_STRIP ||
  92.              prim == PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY) {
  93.             /* make sure we flush even number of triangles at a time */
  94.             if (seg_max < count && !(((seg_max - first) / incr) & 1))
  95.                seg_max -= incr;
  96.          }
  97.  
  98.          do {
  99.             const unsigned remaining = count - seg_start;
  100.  
  101.             if (remaining > seg_max) {
  102.                SEGMENT_SIMPLE(flags, start + seg_start, seg_max);
  103.                seg_start += seg_max - rollback;
  104.  
  105.                flags |= DRAW_SPLIT_BEFORE;
  106.             }
  107.             else {
  108.                flags &= ~DRAW_SPLIT_AFTER;
  109.  
  110.                SEGMENT_SIMPLE(flags, start + seg_start, remaining);
  111.                seg_start += remaining;
  112.             }
  113.          } while (seg_start < count);
  114.          break;
  115.  
  116.       case PIPE_PRIM_LINE_LOOP:
  117.          seg_max =
  118.             draw_pt_trim_count(MIN2(max_count_loop, count), first, incr);
  119.  
  120.          do {
  121.             const unsigned remaining = count - seg_start;
  122.  
  123.             if (remaining > seg_max) {
  124.                SEGMENT_LOOP(flags, start + seg_start, seg_max, start);
  125.                seg_start += seg_max - rollback;
  126.  
  127.                flags |= DRAW_SPLIT_BEFORE;
  128.             }
  129.             else {
  130.                flags &= ~DRAW_SPLIT_AFTER;
  131.  
  132.                SEGMENT_LOOP(flags, start + seg_start, remaining, start);
  133.                seg_start += remaining;
  134.             }
  135.          } while (seg_start < count);
  136.          break;
  137.  
  138.       case PIPE_PRIM_TRIANGLE_FAN:
  139.       case PIPE_PRIM_POLYGON:
  140.          seg_max =
  141.             draw_pt_trim_count(MIN2(max_count_fan, count), first, incr);
  142.  
  143.          do {
  144.             const unsigned remaining = count - seg_start;
  145.  
  146.             if (remaining > seg_max) {
  147.                SEGMENT_FAN(flags, start + seg_start, seg_max, start);
  148.                seg_start += seg_max - rollback;
  149.  
  150.                flags |= DRAW_SPLIT_BEFORE;
  151.             }
  152.             else {
  153.                flags &= ~DRAW_SPLIT_AFTER;
  154.  
  155.                SEGMENT_FAN(flags, start + seg_start, remaining, start);
  156.                seg_start += remaining;
  157.             }
  158.          } while (seg_start < count);
  159.          break;
  160.  
  161.       default:
  162.          assert(0);
  163.          break;
  164.       }
  165.    }
  166. }
  167.  
  168. #undef FUNC
  169. #undef FUNC_VARS
  170. #undef LOCAL_VARS
  171.  
  172. #undef PRIMITIVE
  173. #undef SEGMENT_SIMPLE
  174. #undef SEGMENT_LOOP
  175. #undef SEGMENT_FAN
  176.