Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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 nr,
  30.                                      void *out )
  31. {
  32.    memcpy(out, in, nr*sizeof(short));
  33. }
  34.                              
  35. static void translate_memcpy_uint( const void *in,
  36.                                    unsigned nr,
  37.                                    void *out )
  38. {
  39.    memcpy(out, in, nr*sizeof(int));
  40. }
  41.                              
  42.  
  43. int u_index_translator( unsigned hw_mask,
  44.                         unsigned prim,
  45.                         unsigned in_index_size,
  46.                         unsigned nr,
  47.                         unsigned in_pv,
  48.                         unsigned out_pv,
  49.                         unsigned *out_prim,
  50.                         unsigned *out_index_size,
  51.                         unsigned *out_nr,
  52.                         u_translate_func *out_translate )
  53. {
  54.    unsigned in_idx;
  55.    unsigned out_idx;
  56.    int ret = U_TRANSLATE_NORMAL;
  57.  
  58.    u_index_init();
  59.  
  60.    in_idx = in_size_idx(in_index_size);
  61.    *out_index_size = (in_index_size == 4) ? 4 : 2;
  62.    out_idx = out_size_idx(*out_index_size);
  63.  
  64.    if ((hw_mask & (1<<prim)) &&
  65.        in_index_size == *out_index_size &&
  66.        in_pv == out_pv)
  67.    {
  68.       if (in_index_size == 4)
  69.          *out_translate = translate_memcpy_uint;
  70.       else
  71.          *out_translate = translate_memcpy_ushort;
  72.  
  73.       *out_prim = prim;
  74.       *out_nr = nr;
  75.  
  76.       return U_TRANSLATE_MEMCPY;
  77.    }
  78.    else {
  79.       switch (prim) {
  80.       case PIPE_PRIM_POINTS:
  81.          *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
  82.          *out_prim = PIPE_PRIM_POINTS;
  83.          *out_nr = nr;
  84.          break;
  85.  
  86.       case PIPE_PRIM_LINES:
  87.          *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
  88.          *out_prim = PIPE_PRIM_LINES;
  89.          *out_nr = nr;
  90.          break;
  91.  
  92.       case PIPE_PRIM_LINE_STRIP:
  93.          *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
  94.          *out_prim = PIPE_PRIM_LINES;
  95.          *out_nr = (nr - 1) * 2;
  96.          break;
  97.  
  98.       case PIPE_PRIM_LINE_LOOP:
  99.          *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
  100.          *out_prim = PIPE_PRIM_LINES;
  101.          *out_nr = nr * 2;
  102.          break;
  103.  
  104.       case PIPE_PRIM_TRIANGLES:
  105.          *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
  106.          *out_prim = PIPE_PRIM_TRIANGLES;
  107.          *out_nr = nr;
  108.          break;
  109.  
  110.       case PIPE_PRIM_TRIANGLE_STRIP:
  111.          *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
  112.          *out_prim = PIPE_PRIM_TRIANGLES;
  113.          *out_nr = (nr - 2) * 3;
  114.          break;
  115.  
  116.       case PIPE_PRIM_TRIANGLE_FAN:
  117.          *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
  118.          *out_prim = PIPE_PRIM_TRIANGLES;
  119.          *out_nr = (nr - 2) * 3;
  120.          break;
  121.  
  122.       case PIPE_PRIM_QUADS:
  123.          *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
  124.          *out_prim = PIPE_PRIM_TRIANGLES;
  125.          *out_nr = (nr / 4) * 6;
  126.          break;
  127.  
  128.       case PIPE_PRIM_QUAD_STRIP:
  129.          *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
  130.          *out_prim = PIPE_PRIM_TRIANGLES;
  131.          *out_nr = (nr - 2) * 3;
  132.          break;
  133.  
  134.       case PIPE_PRIM_POLYGON:
  135.          *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
  136.          *out_prim = PIPE_PRIM_TRIANGLES;
  137.          *out_nr = (nr - 2) * 3;
  138.          break;
  139.  
  140.       default:
  141.          assert(0);
  142.          *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
  143.          *out_prim = PIPE_PRIM_POINTS;
  144.          *out_nr = nr;
  145.          return U_TRANSLATE_ERROR;
  146.       }
  147.    }
  148.  
  149.    return ret;
  150. }
  151.  
  152.  
  153. /**
  154.  * If a driver does not support a particular gallium primitive type
  155.  * (such as PIPE_PRIM_QUAD_STRIP) this function can be used to help
  156.  * convert the primitive into a simpler type (like PIPE_PRIM_TRIANGLES).
  157.  *
  158.  * The generator functions generates a number of ushort or uint indexes
  159.  * for drawing the new type of primitive.
  160.  *
  161.  * \param hw_mask  a bitmask of (1 << PIPE_PRIM_x) values that indicates
  162.  *                 kind of primitives are supported by the driver.
  163.  * \param prim  the PIPE_PRIM_x that the user wants to draw
  164.  * \param start  index of first vertex to draw
  165.  * \param nr  number of vertices to draw
  166.  * \param in_pv  user's provoking vertex (PV_FIRST/LAST)
  167.  * \param out_pv  desired proking vertex for the hardware (PV_FIRST/LAST)
  168.  * \param out_prim  returns the new primitive type for the driver
  169.  * \param out_index_size  returns OUT_USHORT or OUT_UINT
  170.  * \param out_nr  returns new number of vertices to draw
  171.  * \param out_generate  returns pointer to the generator function
  172.  */
  173. int u_index_generator( unsigned hw_mask,
  174.                        unsigned prim,
  175.                        unsigned start,
  176.                        unsigned nr,
  177.                        unsigned in_pv,
  178.                        unsigned out_pv,
  179.                        unsigned *out_prim,
  180.                        unsigned *out_index_size,
  181.                        unsigned *out_nr,
  182.                        u_generate_func *out_generate )
  183.  
  184. {
  185.    unsigned out_idx;
  186.  
  187.    u_index_init();
  188.  
  189.    *out_index_size = ((start + nr) > 0xfffe) ? 4 : 2;
  190.    out_idx = out_size_idx(*out_index_size);
  191.  
  192.    if ((hw_mask & (1<<prim)) &&
  193.        (in_pv == out_pv)) {
  194.        
  195.       *out_generate = generate[out_idx][in_pv][out_pv][PIPE_PRIM_POINTS];
  196.       *out_prim = prim;
  197.       *out_nr = nr;
  198.       return U_GENERATE_LINEAR;
  199.    }
  200.    else {
  201.       switch (prim) {
  202.       case PIPE_PRIM_POINTS:
  203.          *out_generate = generate[out_idx][in_pv][out_pv][prim];
  204.          *out_prim = PIPE_PRIM_POINTS;
  205.          *out_nr = nr;
  206.          return U_GENERATE_REUSABLE;
  207.  
  208.       case PIPE_PRIM_LINES:
  209.          *out_generate = generate[out_idx][in_pv][out_pv][prim];
  210.          *out_prim = PIPE_PRIM_LINES;
  211.          *out_nr = nr;
  212.          return U_GENERATE_REUSABLE;
  213.  
  214.       case PIPE_PRIM_LINE_STRIP:
  215.          *out_generate = generate[out_idx][in_pv][out_pv][prim];
  216.          *out_prim = PIPE_PRIM_LINES;
  217.          *out_nr = (nr - 1) * 2;
  218.          return U_GENERATE_REUSABLE;
  219.  
  220.       case PIPE_PRIM_LINE_LOOP:
  221.          *out_generate = generate[out_idx][in_pv][out_pv][prim];
  222.          *out_prim = PIPE_PRIM_LINES;
  223.          *out_nr = nr * 2;
  224.          return U_GENERATE_ONE_OFF;
  225.  
  226.       case PIPE_PRIM_TRIANGLES:
  227.          *out_generate = generate[out_idx][in_pv][out_pv][prim];
  228.          *out_prim = PIPE_PRIM_TRIANGLES;
  229.          *out_nr = nr;
  230.          return U_GENERATE_REUSABLE;
  231.  
  232.       case PIPE_PRIM_TRIANGLE_STRIP:
  233.          *out_generate = generate[out_idx][in_pv][out_pv][prim];
  234.          *out_prim = PIPE_PRIM_TRIANGLES;
  235.          *out_nr = (nr - 2) * 3;
  236.          return U_GENERATE_REUSABLE;
  237.  
  238.       case PIPE_PRIM_TRIANGLE_FAN:
  239.          *out_generate = generate[out_idx][in_pv][out_pv][prim];
  240.          *out_prim = PIPE_PRIM_TRIANGLES;
  241.          *out_nr = (nr - 2) * 3;
  242.          return U_GENERATE_REUSABLE;
  243.  
  244.       case PIPE_PRIM_QUADS:
  245.          *out_generate = generate[out_idx][in_pv][out_pv][prim];
  246.          *out_prim = PIPE_PRIM_TRIANGLES;
  247.          *out_nr = (nr / 4) * 6;
  248.          return U_GENERATE_REUSABLE;
  249.  
  250.       case PIPE_PRIM_QUAD_STRIP:
  251.          *out_generate = generate[out_idx][in_pv][out_pv][prim];
  252.          *out_prim = PIPE_PRIM_TRIANGLES;
  253.          *out_nr = (nr - 2) * 3;
  254.          return U_GENERATE_REUSABLE;
  255.  
  256.       case PIPE_PRIM_POLYGON:
  257.          *out_generate = generate[out_idx][in_pv][out_pv][prim];
  258.          *out_prim = PIPE_PRIM_TRIANGLES;
  259.          *out_nr = (nr - 2) * 3;
  260.          return U_GENERATE_REUSABLE;
  261.  
  262.       default:
  263.          assert(0);
  264.          *out_generate = generate[out_idx][in_pv][out_pv][PIPE_PRIM_POINTS];
  265.          *out_prim = PIPE_PRIM_POINTS;
  266.          *out_nr = nr;
  267.          return U_TRANSLATE_ERROR;
  268.       }
  269.    }
  270. }
  271.