Home | History | Annotate | Download | only in indices
      1 /*
      2  * Copyright 2009 VMware, Inc.
      3  * All Rights Reserved.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the "Software"),
      7  * to deal in the Software without restriction, including without limitation
      8  * on the rights to use, copy, modify, merge, publish, distribute, sub
      9  * license, and/or sell copies of the Software, and to permit persons to whom
     10  * the Software is furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice (including the next
     13  * paragraph) shall be included in all copies or substantial portions of the
     14  * Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
     19  * VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
     20  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     21  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     22  * USE OR OTHER DEALINGS IN THE SOFTWARE.
     23  */
     24 
     25 #include "u_indices.h"
     26 #include "u_indices_priv.h"
     27 
     28 
     29 static void translate_ubyte_ushort( const void *in,
     30                                     unsigned nr,
     31                                     void *out )
     32 {
     33    const ubyte *in_ub = (const ubyte *)in;
     34    ushort *out_us = (ushort *)out;
     35    unsigned i;
     36    for (i = 0; i < nr; i++)
     37       out_us[i] = (ushort) in_ub[i];
     38 }
     39 
     40 static void translate_memcpy_ushort( const void *in,
     41                                      unsigned nr,
     42                                      void *out )
     43 {
     44    memcpy(out, in, nr*sizeof(short));
     45 }
     46 
     47 static void translate_memcpy_uint( const void *in,
     48                                    unsigned nr,
     49                                    void *out )
     50 {
     51    memcpy(out, in, nr*sizeof(int));
     52 }
     53 
     54 
     55 static void generate_linear_ushort( unsigned nr,
     56                                     void *out )
     57 {
     58    ushort *out_us = (ushort *)out;
     59    unsigned i;
     60    for (i = 0; i < nr; i++)
     61       out_us[i] = (ushort) i;
     62 }
     63 
     64 static void generate_linear_uint( unsigned nr,
     65                                   void *out )
     66 {
     67    unsigned *out_ui = (unsigned *)out;
     68    unsigned i;
     69    for (i = 0; i < nr; i++)
     70       out_ui[i] = i;
     71 }
     72 
     73 
     74 /**
     75  * Given a primitive type and number of vertices, return the number of vertices
     76  * needed to draw the primitive with fill mode = PIPE_POLYGON_MODE_LINE using
     77  * separate lines (PIPE_PRIM_LINES).
     78  */
     79 static unsigned nr_lines( unsigned prim,
     80                           unsigned nr )
     81 {
     82    switch (prim) {
     83    case PIPE_PRIM_TRIANGLES:
     84       return (nr / 3) * 6;
     85    case PIPE_PRIM_TRIANGLE_STRIP:
     86       return (nr - 2) * 6;
     87    case PIPE_PRIM_TRIANGLE_FAN:
     88       return (nr - 2)  * 6;
     89    case PIPE_PRIM_QUADS:
     90       return (nr / 4) * 8;
     91    case PIPE_PRIM_QUAD_STRIP:
     92       return (nr - 2) / 2 * 8;
     93    case PIPE_PRIM_POLYGON:
     94       return 2 * nr; /* a line (two verts) for each polygon edge */
     95    default:
     96       assert(0);
     97       return 0;
     98    }
     99 }
    100 
    101 
    102 
    103 int u_unfilled_translator( unsigned prim,
    104                         unsigned in_index_size,
    105                         unsigned nr,
    106                         unsigned unfilled_mode,
    107                         unsigned *out_prim,
    108                         unsigned *out_index_size,
    109                         unsigned *out_nr,
    110                         u_translate_func *out_translate )
    111 {
    112    unsigned in_idx;
    113    unsigned out_idx;
    114 
    115    u_unfilled_init();
    116 
    117    in_idx = in_size_idx(in_index_size);
    118    *out_index_size = (in_index_size == 4) ? 4 : 2;
    119    out_idx = out_size_idx(*out_index_size);
    120 
    121    if (unfilled_mode == PIPE_POLYGON_MODE_POINT)
    122    {
    123       *out_prim = PIPE_PRIM_POINTS;
    124       *out_nr = nr;
    125 
    126       switch (in_index_size)
    127       {
    128       case 1:
    129          *out_translate = translate_ubyte_ushort;
    130          return U_TRANSLATE_NORMAL;
    131       case 2:
    132          *out_translate = translate_memcpy_uint;
    133          return U_TRANSLATE_MEMCPY;
    134       case 4:
    135          *out_translate = translate_memcpy_ushort;
    136          return U_TRANSLATE_MEMCPY;
    137       default:
    138          *out_translate = translate_memcpy_uint;
    139          *out_nr = 0;
    140          assert(0);
    141          return U_TRANSLATE_ERROR;
    142       }
    143    }
    144    else {
    145       assert(unfilled_mode == PIPE_POLYGON_MODE_LINE);
    146       *out_prim = PIPE_PRIM_LINES;
    147       *out_translate = translate_line[in_idx][out_idx][prim];
    148       *out_nr = nr_lines( prim, nr );
    149       return U_TRANSLATE_NORMAL;
    150    }
    151 }
    152 
    153 
    154 
    155 int u_unfilled_generator( unsigned prim,
    156                           unsigned start,
    157                           unsigned nr,
    158                           unsigned unfilled_mode,
    159                           unsigned *out_prim,
    160                           unsigned *out_index_size,
    161                           unsigned *out_nr,
    162                           u_generate_func *out_generate )
    163 {
    164    unsigned out_idx;
    165 
    166    u_unfilled_init();
    167 
    168    *out_index_size = ((start + nr) > 0xfffe) ? 4 : 2;
    169    out_idx = out_size_idx(*out_index_size);
    170 
    171    if (unfilled_mode == PIPE_POLYGON_MODE_POINT) {
    172 
    173       if (*out_index_size == 4)
    174          *out_generate = generate_linear_uint;
    175       else
    176          *out_generate = generate_linear_ushort;
    177 
    178       *out_prim = PIPE_PRIM_POINTS;
    179       *out_nr = nr;
    180       return U_GENERATE_LINEAR;
    181    }
    182    else {
    183       assert(unfilled_mode == PIPE_POLYGON_MODE_LINE);
    184       *out_prim = PIPE_PRIM_LINES;
    185       *out_generate = generate_line[out_idx][prim];
    186       *out_nr = nr_lines( prim, nr );
    187 
    188       return U_GENERATE_REUSABLE;
    189    }
    190 }
    191 
    192