u_indices.c revision 4a49301e
11.1563Smaya/*
21.1048Sjdc * Copyright 2009 VMware, Inc.
31.1048Sjdc * All Rights Reserved.
41.1048Sjdc *
51.657Slukem * Permission is hereby granted, free of charge, to any person obtaining a
61.653Slukem * copy of this software and associated documentation files (the "Software"),
71.1157Sskrll * to deal in the Software without restriction, including without limitation
81.1266Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub
91.1157Sskrll * license, and/or sell copies of the Software, and to permit persons to whom
101.1157Sskrll * the Software is furnished to do so, subject to the following conditions:
111.1087Slukem *
121.891Sriz * The above copyright notice and this permission notice (including the next
131.653Slukem * paragraph) shall be included in all copies or substantial portions of the
141.653Slukem * Software.
151.1553Skre *
161.653Slukem * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
171.653Slukem * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
181.1172Schristos * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
191.650Slukem * VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
201.1503Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
211.891Sriz * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
221.665Sscw * USE OR OTHER DEALINGS IN THE SOFTWARE.
231.1476Schristos */
241.653Slukem
251.1157Sskrll#include "u_indices.h"
261.1375Sjoerg#include "u_indices_priv.h"
271.1176Smatt
281.670Smrgstatic void translate_memcpy_ushort( const void *in,
291.653Slukem                                     unsigned nr,
301.653Slukem                                     void *out )
311.653Slukem{
321.650Slukem   memcpy(out, in, nr*sizeof(short));
331.867Schristos}
341.1157Sskrll
351.653Slukemstatic void translate_memcpy_uint( const void *in,
361.665Sscw                                   unsigned nr,
371.650Slukem                                   void *out )
381.653Slukem{
391.950Schristos   memcpy(out, in, nr*sizeof(int));
401.1217Sriz}
411.651Slukem
421.651Slukem
431.1353Schristosint u_index_translator( unsigned hw_mask,
441.651Slukem                        unsigned prim,
451.651Slukem                        unsigned in_index_size,
461.650Slukem                        unsigned nr,
471.651Slukem                        unsigned in_pv,
481.651Slukem                        unsigned out_pv,
491.1340Schristos                        unsigned *out_prim,
501.651Slukem                        unsigned *out_index_size,
511.651Slukem                        unsigned *out_nr,
521.651Slukem                        u_translate_func *out_translate )
531.1177Suebayasi{
541.1223Sjmmv   unsigned in_idx;
551.1215Sjmmv   unsigned out_idx;
561.1422Sjmmv   int ret = U_TRANSLATE_NORMAL;
571.1422Sjmmv
581.1542Swiz   u_index_init();
591.1223Sjmmv
601.1183Swiz   in_idx = in_size_idx(in_index_size);
611.1176Smatt   *out_index_size = (in_index_size == 4) ? 4 : 2;
621.1422Sjmmv   out_idx = out_size_idx(*out_index_size);
631.1176Smatt
641.1422Sjmmv   if ((hw_mask & (1<<prim)) &&
651.1215Sjmmv       in_index_size == *out_index_size &&
661.1176Smatt       in_pv == out_pv)
671.1422Sjmmv   {
681.1422Sjmmv      if (in_index_size == 4)
691.1422Sjmmv         *out_translate = translate_memcpy_uint;
701.651Slukem      else
711.651Slukem         *out_translate = translate_memcpy_ushort;
721.1350Swiz
731.651Slukem      *out_prim = prim;
741.651Slukem      *out_nr = nr;
751.651Slukem
761.1121Sjoerg      return U_TRANSLATE_MEMCPY;
771.651Slukem   }
781.651Slukem   else {
791.651Slukem      switch (prim) {
801.651Slukem      case PIPE_PRIM_POINTS:
811.651Slukem         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
821.1556Sriastrad         *out_prim = PIPE_PRIM_POINTS;
831.651Slukem         *out_nr = nr;
841.651Slukem         break;
851.1556Sriastrad
861.898Sgdamore      case PIPE_PRIM_LINES:
871.1033Splunky         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
881.898Sgdamore         *out_prim = PIPE_PRIM_LINES;
891.651Slukem         *out_nr = nr;
901.651Slukem         break;
911.651Slukem
921.651Slukem      case PIPE_PRIM_LINE_STRIP:
931.651Slukem         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
941.651Slukem         *out_prim = PIPE_PRIM_LINES;
951.651Slukem         *out_nr = (nr - 1) * 2;
961.651Slukem         break;
971.1317Splunky
981.651Slukem      case PIPE_PRIM_LINE_LOOP:
991.651Slukem         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
1001.651Slukem         *out_prim = PIPE_PRIM_LINES;
1011.651Slukem         *out_nr = nr * 2;
1021.651Slukem         break;
1031.651Slukem
1041.651Slukem      case PIPE_PRIM_TRIANGLES:
1051.651Slukem         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
1061.651Slukem         *out_prim = PIPE_PRIM_TRIANGLES;
1071.651Slukem         *out_nr = nr;
1081.651Slukem         break;
1091.1350Swiz
1101.651Slukem      case PIPE_PRIM_TRIANGLE_STRIP:
1111.651Slukem         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
1121.651Slukem         *out_prim = PIPE_PRIM_TRIANGLES;
1131.651Slukem         *out_nr = (nr - 2) * 3;
1141.651Slukem         break;
1151.651Slukem
1161.651Slukem      case PIPE_PRIM_TRIANGLE_FAN:
1171.651Slukem         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
1181.1309Selric         *out_prim = PIPE_PRIM_TRIANGLES;
1191.651Slukem         *out_nr = (nr - 2) * 3;
1201.651Slukem         break;
1211.651Slukem
1221.891Sriz      case PIPE_PRIM_QUADS:
1231.651Slukem         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
1241.651Slukem         *out_prim = PIPE_PRIM_TRIANGLES;
1251.933Schristos         *out_nr = (nr / 4) * 6;
1261.651Slukem         break;
1271.1466Sozaki
1281.1466Sozaki      case PIPE_PRIM_QUAD_STRIP:
1291.1466Sozaki         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
1301.894Sdan         *out_prim = PIPE_PRIM_TRIANGLES;
1311.651Slukem         *out_nr = (nr - 2) * 3;
1321.651Slukem         break;
1331.651Slukem
1341.651Slukem      case PIPE_PRIM_POLYGON:
1351.651Slukem         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
1361.651Slukem         *out_prim = PIPE_PRIM_TRIANGLES;
1371.1478Sspz         *out_nr = (nr - 2) * 3;
1381.799Sperry         break;
1391.651Slukem
1401.651Slukem      default:
1411.651Slukem         assert(0);
1421.651Slukem         *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim];
1431.651Slukem         *out_prim = PIPE_PRIM_POINTS;
1441.651Slukem         *out_nr = nr;
1451.1159Stsarna         return U_TRANSLATE_ERROR;
1461.733Swiz      }
1471.733Swiz   }
1481.651Slukem
1491.1121Sjoerg   return ret;
1501.651Slukem}
1511.1192Sdarran
1521.651Slukem
1531.651Slukem
1541.651Slukem
1551.651Slukem
1561.651Slukemint u_index_generator( unsigned hw_mask,
1571.1484Sapb                       unsigned prim,
1581.651Slukem                       unsigned start,
1591.651Slukem                       unsigned nr,
1601.651Slukem                       unsigned in_pv,
1611.651Slukem                       unsigned out_pv,
1621.651Slukem                       unsigned *out_prim,
1631.651Slukem                       unsigned *out_index_size,
1641.651Slukem                       unsigned *out_nr,
1651.651Slukem                       u_generate_func *out_generate )
1661.651Slukem
1671.651Slukem{
1681.1362Syamt   unsigned out_idx;
1691.651Slukem
1701.651Slukem   u_index_init();
1711.1404Schristos
1721.651Slukem   *out_index_size = ((start + nr) > 0xfffe) ? 4 : 2;
1731.651Slukem   out_idx = out_size_idx(*out_index_size);
1741.651Slukem
1751.651Slukem   if ((hw_mask & (1<<prim)) &&
1761.651Slukem       (in_pv == out_pv)) {
1771.651Slukem
1781.651Slukem      *out_generate = generate[out_idx][in_pv][out_pv][PIPE_PRIM_POINTS];
1791.650Slukem      *out_prim = prim;
1801.891Sriz      *out_nr = nr;
1811.651Slukem      return U_GENERATE_LINEAR;
1821.1469Sginsbach   }
1831.1348Schristos   else {
1841.651Slukem      switch (prim) {
1851.734Slukem      case PIPE_PRIM_POINTS:
1861.742Sthorpej         *out_generate = generate[out_idx][in_pv][out_pv][prim];
1871.802Swiz         *out_prim = PIPE_PRIM_POINTS;
1881.786Schristos         *out_nr = nr;
1891.1485Sapb         return U_GENERATE_REUSABLE;
1901.651Slukem
1911.817Srpaulo      case PIPE_PRIM_LINES:
1921.651Slukem         *out_generate = generate[out_idx][in_pv][out_pv][prim];
1931.651Slukem         *out_prim = PIPE_PRIM_LINES;
1941.651Slukem         *out_nr = nr;
1951.651Slukem         return U_GENERATE_REUSABLE;
1961.651Slukem
1971.651Slukem      case PIPE_PRIM_LINE_STRIP:
1981.651Slukem         *out_generate = generate[out_idx][in_pv][out_pv][prim];
1991.651Slukem         *out_prim = PIPE_PRIM_LINES;
2001.651Slukem         *out_nr = (nr - 1) * 2;
2011.651Slukem         return U_GENERATE_REUSABLE;
2021.651Slukem
2031.1284Stsutsui      case PIPE_PRIM_LINE_LOOP:
2041.650Slukem         *out_generate = generate[out_idx][in_pv][out_pv][prim];
2051.650Slukem         *out_prim = PIPE_PRIM_LINES;
2061.650Slukem         *out_nr = nr * 2;
2071.650Slukem         return U_GENERATE_ONE_OFF;
2081.650Slukem
2091.650Slukem      case PIPE_PRIM_TRIANGLES:
2101.650Slukem         *out_generate = generate[out_idx][in_pv][out_pv][prim];
2111.650Slukem         *out_prim = PIPE_PRIM_TRIANGLES;
2121.650Slukem         *out_nr = nr;
2131.650Slukem         return U_GENERATE_REUSABLE;
2141.651Slukem
2151.651Slukem      case PIPE_PRIM_TRIANGLE_STRIP:
2161.651Slukem         *out_generate = generate[out_idx][in_pv][out_pv][prim];
2171.651Slukem         *out_prim = PIPE_PRIM_TRIANGLES;
2181.651Slukem         *out_nr = (nr - 2) * 3;
2191.1186Sroy         return U_GENERATE_REUSABLE;
2201.713Swiz
2211.651Slukem      case PIPE_PRIM_TRIANGLE_FAN:
2221.651Slukem         *out_generate = generate[out_idx][in_pv][out_pv][prim];
2231.651Slukem         *out_prim = PIPE_PRIM_TRIANGLES;
2241.651Slukem         *out_nr = (nr - 2) * 3;
2251.651Slukem         return U_GENERATE_REUSABLE;
2261.651Slukem
2271.763Speter      case PIPE_PRIM_QUADS:
2281.763Speter         *out_generate = generate[out_idx][in_pv][out_pv][prim];
2291.763Speter         *out_prim = PIPE_PRIM_TRIANGLES;
2301.763Speter         *out_nr = (nr / 4) * 6;
2311.651Slukem         return U_GENERATE_REUSABLE;
2321.651Slukem
2331.651Slukem      case PIPE_PRIM_QUAD_STRIP:
2341.651Slukem         *out_generate = generate[out_idx][in_pv][out_pv][prim];
2351.651Slukem         *out_prim = PIPE_PRIM_TRIANGLES;
2361.650Slukem         *out_nr = (nr - 2) * 3;
2371.705Sbsh         return U_GENERATE_REUSABLE;
2381.651Slukem
2391.1309Selric      case PIPE_PRIM_POLYGON:
2401.651Slukem         *out_generate = generate[out_idx][in_pv][out_pv][prim];
2411.651Slukem         *out_prim = PIPE_PRIM_TRIANGLES;
2421.1371Sjoerg         *out_nr = (nr - 2) * 3;
2431.1059Smlelstv         return U_GENERATE_REUSABLE;
2441.651Slukem
2451.651Slukem      default:
2461.651Slukem         assert(0);
2471.1467Schristos         *out_generate = generate[out_idx][in_pv][out_pv][PIPE_PRIM_POINTS];
2481.1421Sjmmv         *out_prim = PIPE_PRIM_POINTS;
2491.1420Sjmmv         *out_nr = nr;
2501.1421Sjmmv         return U_TRANSLATE_ERROR;
2511.1421Sjmmv      }
2521.1421Sjmmv   }
2531.1421Sjmmv}
2541.1421Sjmmv