"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/gallium/auxiliary/indices/u_indices.c" (16 Sep 2020, 10645 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "u_indices.c" see the Fossies "Dox" file reference documentation.

    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 static void translate_memcpy_ushort( const void *in,
   29                                      unsigned start,
   30                                      unsigned in_nr,
   31                                      unsigned out_nr,
   32                                      unsigned restart_index,
   33                                      void *out )
   34 {
   35    memcpy(out, &((short *)in)[start], out_nr*sizeof(short));
   36 }
   37                               
   38 static void translate_memcpy_uint( const void *in,
   39                                    unsigned start,
   40                                    unsigned in_nr,
   41                                    unsigned out_nr,
   42                                    unsigned restart_index,
   43                                    void *out )
   44 {
   45    memcpy(out, &((int *)in)[start], out_nr*sizeof(int));
   46 }
   47                               
   48 
   49 /**
   50  * Translate indexes when a driver can't support certain types
   51  * of drawing.  Example include:
   52  * - Translate 1-byte indexes into 2-byte indexes
   53  * - Translate PIPE_PRIM_QUADS into PIPE_PRIM_TRIANGLES when the hardware
   54  *   doesn't support the former.
   55  * - Translate from first provoking vertex to last provoking vertex and
   56  *   vice versa.
   57  *
   58  * Note that this function is used for indexed primitives.
   59  *
   60  * \param hw_mask  mask of (1 << PIPE_PRIM_x) flags indicating which types
   61  *                 of primitives are supported by the hardware.
   62  * \param prim  incoming PIPE_PRIM_x
   63  * \param in_index_size  bytes per index value (1, 2 or 4)
   64  * \param nr  number of incoming vertices
   65  * \param in_pv  incoming provoking vertex convention (PV_FIRST or PV_LAST)
   66  * \param out_pv  desired provoking vertex convention (PV_FIRST or PV_LAST)
   67  * \param prim_restart  whether primitive restart is disable or enabled
   68  * \param out_prim  returns new PIPE_PRIM_x we'll translate to
   69  * \param out_index_size  returns bytes per new index value (2 or 4)
   70  * \param out_nr  returns number of new vertices
   71  * \param out_translate  returns the translation function to use by the caller
   72  */
   73 enum indices_mode
   74 u_index_translator(unsigned hw_mask,
   75                    enum pipe_prim_type prim,
   76                    unsigned in_index_size,
   77                    unsigned nr,
   78                    unsigned in_pv,
   79                    unsigned out_pv,
   80                    unsigned prim_restart,
   81                    enum pipe_prim_type *out_prim,
   82                    unsigned *out_index_size,
   83                    unsigned *out_nr,
   84                    u_translate_func *out_translate)
   85 {
   86    unsigned in_idx;
   87    unsigned out_idx;
   88    enum indices_mode ret = U_TRANSLATE_NORMAL;
   89 
   90    assert(in_index_size == 1 ||
   91           in_index_size == 2 ||
   92           in_index_size == 4);
   93 
   94    u_index_init();
   95 
   96    in_idx = in_size_idx(in_index_size);
   97    *out_index_size = (in_index_size == 4) ? 4 : 2;
   98    out_idx = out_size_idx(*out_index_size);
   99 
  100    if ((hw_mask & (1<<prim)) && 
  101        in_index_size == *out_index_size &&
  102        in_pv == out_pv) 
  103    {
  104       /* Index translation not really needed */
  105       if (in_index_size == 4)
  106          *out_translate = translate_memcpy_uint;
  107       else
  108          *out_translate = translate_memcpy_ushort;
  109 
  110       *out_prim = prim;
  111       *out_nr = nr;
  112 
  113       return U_TRANSLATE_MEMCPY;
  114    }
  115    else {
  116       *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim_restart][prim];
  117 
  118       switch (prim) {
  119       case PIPE_PRIM_POINTS:
  120          *out_prim = PIPE_PRIM_POINTS;
  121          *out_nr = nr;
  122          break;
  123 
  124       case PIPE_PRIM_LINES:
  125          *out_prim = PIPE_PRIM_LINES;
  126          *out_nr = nr;
  127          break;
  128 
  129       case PIPE_PRIM_LINE_STRIP:
  130          *out_prim = PIPE_PRIM_LINES;
  131          *out_nr = (nr - 1) * 2;
  132          break;
  133 
  134       case PIPE_PRIM_LINE_LOOP:
  135          *out_prim = PIPE_PRIM_LINES;
  136          *out_nr = nr * 2;
  137          break;
  138 
  139       case PIPE_PRIM_TRIANGLES:
  140          *out_prim = PIPE_PRIM_TRIANGLES;
  141          *out_nr = nr;
  142          break;
  143 
  144       case PIPE_PRIM_TRIANGLE_STRIP:
  145          *out_prim = PIPE_PRIM_TRIANGLES;
  146          *out_nr = (nr - 2) * 3;
  147          break;
  148 
  149       case PIPE_PRIM_TRIANGLE_FAN:
  150          *out_prim = PIPE_PRIM_TRIANGLES;
  151          *out_nr = (nr - 2) * 3;
  152          break;
  153 
  154       case PIPE_PRIM_QUADS:
  155          *out_prim = PIPE_PRIM_TRIANGLES;
  156          *out_nr = (nr / 4) * 6;
  157          break;
  158 
  159       case PIPE_PRIM_QUAD_STRIP:
  160          *out_prim = PIPE_PRIM_TRIANGLES;
  161          *out_nr = (nr - 2) * 3;
  162          break;
  163 
  164       case PIPE_PRIM_POLYGON:
  165          *out_prim = PIPE_PRIM_TRIANGLES;
  166          *out_nr = (nr - 2) * 3;
  167          break;
  168 
  169       case PIPE_PRIM_LINES_ADJACENCY:
  170          *out_prim = PIPE_PRIM_LINES_ADJACENCY;
  171          *out_nr = nr;
  172          break;
  173 
  174       case PIPE_PRIM_LINE_STRIP_ADJACENCY:
  175          *out_prim = PIPE_PRIM_LINES_ADJACENCY;
  176          *out_nr = (nr - 3) * 4;
  177          break;
  178 
  179       case PIPE_PRIM_TRIANGLES_ADJACENCY:
  180          *out_prim = PIPE_PRIM_TRIANGLES_ADJACENCY;
  181          *out_nr = nr;
  182          break;
  183 
  184       case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
  185          *out_prim = PIPE_PRIM_TRIANGLES_ADJACENCY;
  186          *out_nr = ((nr - 4) / 2) * 6;
  187          break;
  188 
  189       default:
  190          assert(0);
  191          *out_prim = PIPE_PRIM_POINTS;
  192          *out_nr = nr;
  193          return U_TRANSLATE_ERROR;
  194       }
  195    }
  196 
  197    return ret;
  198 }
  199 
  200 
  201 /**
  202  * If a driver does not support a particular gallium primitive type
  203  * (such as PIPE_PRIM_QUAD_STRIP) this function can be used to help
  204  * convert the primitive into a simpler type (like PIPE_PRIM_TRIANGLES).
  205  *
  206  * The generator functions generates a number of ushort or uint indexes
  207  * for drawing the new type of primitive.
  208  *
  209  * Note that this function is used for non-indexed primitives.
  210  *
  211  * \param hw_mask  a bitmask of (1 << PIPE_PRIM_x) values that indicates
  212  *                 kind of primitives are supported by the driver.
  213  * \param prim  the PIPE_PRIM_x that the user wants to draw
  214  * \param start  index of first vertex to draw
  215  * \param nr  number of vertices to draw
  216  * \param in_pv  user's provoking vertex (PV_FIRST/LAST)
  217  * \param out_pv  desired proking vertex for the hardware (PV_FIRST/LAST)
  218  * \param out_prim  returns the new primitive type for the driver
  219  * \param out_index_size  returns OUT_USHORT or OUT_UINT
  220  * \param out_nr  returns new number of vertices to draw
  221  * \param out_generate  returns pointer to the generator function
  222  */
  223 enum indices_mode
  224 u_index_generator(unsigned hw_mask,
  225                   enum pipe_prim_type prim,
  226                   unsigned start,
  227                   unsigned nr,
  228                   unsigned in_pv,
  229                   unsigned out_pv,
  230                   enum pipe_prim_type *out_prim,
  231                   unsigned *out_index_size,
  232                   unsigned *out_nr,
  233                   u_generate_func *out_generate)
  234 {
  235    unsigned out_idx;
  236 
  237    u_index_init();
  238 
  239    *out_index_size = ((start + nr) > 0xfffe) ? 4 : 2;
  240    out_idx = out_size_idx(*out_index_size);
  241 
  242    if ((hw_mask & (1<<prim)) && 
  243        (in_pv == out_pv)) {
  244        
  245       *out_generate = generate[out_idx][in_pv][out_pv][PIPE_PRIM_POINTS];
  246       *out_prim = prim;
  247       *out_nr = nr;
  248       return U_GENERATE_LINEAR;
  249    }
  250    else {
  251       *out_generate = generate[out_idx][in_pv][out_pv][prim];
  252 
  253       switch (prim) {
  254       case PIPE_PRIM_POINTS:
  255          *out_prim = PIPE_PRIM_POINTS;
  256          *out_nr = nr;
  257          return U_GENERATE_REUSABLE;
  258 
  259       case PIPE_PRIM_LINES:
  260          *out_prim = PIPE_PRIM_LINES;
  261          *out_nr = nr;
  262          return U_GENERATE_REUSABLE;
  263 
  264       case PIPE_PRIM_LINE_STRIP:
  265          *out_prim = PIPE_PRIM_LINES;
  266          *out_nr = (nr - 1) * 2;
  267          return U_GENERATE_REUSABLE;
  268 
  269       case PIPE_PRIM_LINE_LOOP:
  270          *out_prim = PIPE_PRIM_LINES;
  271          *out_nr = nr * 2;
  272          return U_GENERATE_ONE_OFF;
  273 
  274       case PIPE_PRIM_TRIANGLES:
  275          *out_prim = PIPE_PRIM_TRIANGLES;
  276          *out_nr = nr;
  277          return U_GENERATE_REUSABLE;
  278 
  279       case PIPE_PRIM_TRIANGLE_STRIP:
  280          *out_prim = PIPE_PRIM_TRIANGLES;
  281          *out_nr = (nr - 2) * 3;
  282          return U_GENERATE_REUSABLE;
  283 
  284       case PIPE_PRIM_TRIANGLE_FAN:
  285          *out_prim = PIPE_PRIM_TRIANGLES;
  286          *out_nr = (nr - 2) * 3;
  287          return U_GENERATE_REUSABLE;
  288 
  289       case PIPE_PRIM_QUADS:
  290          *out_prim = PIPE_PRIM_TRIANGLES;
  291          *out_nr = (nr / 4) * 6;
  292          return U_GENERATE_REUSABLE;
  293 
  294       case PIPE_PRIM_QUAD_STRIP:
  295          *out_prim = PIPE_PRIM_TRIANGLES;
  296          *out_nr = (nr - 2) * 3;
  297          return U_GENERATE_REUSABLE;
  298 
  299       case PIPE_PRIM_POLYGON:
  300          *out_prim = PIPE_PRIM_TRIANGLES;
  301          *out_nr = (nr - 2) * 3;
  302          return U_GENERATE_REUSABLE;
  303 
  304       case PIPE_PRIM_LINES_ADJACENCY:
  305          *out_prim = PIPE_PRIM_LINES_ADJACENCY;
  306          *out_nr = nr;
  307          return U_GENERATE_REUSABLE;
  308 
  309       case PIPE_PRIM_LINE_STRIP_ADJACENCY:
  310          *out_prim = PIPE_PRIM_LINES_ADJACENCY;
  311          *out_nr = (nr - 3) * 4;
  312          return U_GENERATE_REUSABLE;
  313 
  314       case PIPE_PRIM_TRIANGLES_ADJACENCY:
  315          *out_prim = PIPE_PRIM_TRIANGLES_ADJACENCY;
  316          *out_nr = nr;
  317          return U_GENERATE_REUSABLE;
  318 
  319       case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
  320          *out_prim = PIPE_PRIM_TRIANGLES_ADJACENCY;
  321          *out_nr = ((nr - 4) / 2) * 6;
  322          return U_GENERATE_REUSABLE;
  323 
  324       default:
  325          assert(0);
  326          *out_generate = generate[out_idx][in_pv][out_pv][PIPE_PRIM_POINTS];
  327          *out_prim = PIPE_PRIM_POINTS;
  328          *out_nr = nr;
  329          return U_TRANSLATE_ERROR;
  330       }
  331    }
  332 }