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
28static void translate_memcpy_ushort( const void *in,
29                                     unsigned nr,
30                                     void *out )
31{
32   memcpy(out, in, nr*sizeof(short));
33}
34
35static void translate_memcpy_uint( const void *in,
36                                   unsigned nr,
37                                   void *out )
38{
39   memcpy(out, in, nr*sizeof(int));
40}
41
42
43int 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
155
156int u_index_generator( unsigned hw_mask,
157                       unsigned prim,
158                       unsigned start,
159                       unsigned nr,
160                       unsigned in_pv,
161                       unsigned out_pv,
162                       unsigned *out_prim,
163                       unsigned *out_index_size,
164                       unsigned *out_nr,
165                       u_generate_func *out_generate )
166
167{
168   unsigned out_idx;
169
170   u_index_init();
171
172   *out_index_size = ((start + nr) > 0xfffe) ? 4 : 2;
173   out_idx = out_size_idx(*out_index_size);
174
175   if ((hw_mask & (1<<prim)) &&
176       (in_pv == out_pv)) {
177
178      *out_generate = generate[out_idx][in_pv][out_pv][PIPE_PRIM_POINTS];
179      *out_prim = prim;
180      *out_nr = nr;
181      return U_GENERATE_LINEAR;
182   }
183   else {
184      switch (prim) {
185      case PIPE_PRIM_POINTS:
186         *out_generate = generate[out_idx][in_pv][out_pv][prim];
187         *out_prim = PIPE_PRIM_POINTS;
188         *out_nr = nr;
189         return U_GENERATE_REUSABLE;
190
191      case PIPE_PRIM_LINES:
192         *out_generate = generate[out_idx][in_pv][out_pv][prim];
193         *out_prim = PIPE_PRIM_LINES;
194         *out_nr = nr;
195         return U_GENERATE_REUSABLE;
196
197      case PIPE_PRIM_LINE_STRIP:
198         *out_generate = generate[out_idx][in_pv][out_pv][prim];
199         *out_prim = PIPE_PRIM_LINES;
200         *out_nr = (nr - 1) * 2;
201         return U_GENERATE_REUSABLE;
202
203      case PIPE_PRIM_LINE_LOOP:
204         *out_generate = generate[out_idx][in_pv][out_pv][prim];
205         *out_prim = PIPE_PRIM_LINES;
206         *out_nr = nr * 2;
207         return U_GENERATE_ONE_OFF;
208
209      case PIPE_PRIM_TRIANGLES:
210         *out_generate = generate[out_idx][in_pv][out_pv][prim];
211         *out_prim = PIPE_PRIM_TRIANGLES;
212         *out_nr = nr;
213         return U_GENERATE_REUSABLE;
214
215      case PIPE_PRIM_TRIANGLE_STRIP:
216         *out_generate = generate[out_idx][in_pv][out_pv][prim];
217         *out_prim = PIPE_PRIM_TRIANGLES;
218         *out_nr = (nr - 2) * 3;
219         return U_GENERATE_REUSABLE;
220
221      case PIPE_PRIM_TRIANGLE_FAN:
222         *out_generate = generate[out_idx][in_pv][out_pv][prim];
223         *out_prim = PIPE_PRIM_TRIANGLES;
224         *out_nr = (nr - 2) * 3;
225         return U_GENERATE_REUSABLE;
226
227      case PIPE_PRIM_QUADS:
228         *out_generate = generate[out_idx][in_pv][out_pv][prim];
229         *out_prim = PIPE_PRIM_TRIANGLES;
230         *out_nr = (nr / 4) * 6;
231         return U_GENERATE_REUSABLE;
232
233      case PIPE_PRIM_QUAD_STRIP:
234         *out_generate = generate[out_idx][in_pv][out_pv][prim];
235         *out_prim = PIPE_PRIM_TRIANGLES;
236         *out_nr = (nr - 2) * 3;
237         return U_GENERATE_REUSABLE;
238
239      case PIPE_PRIM_POLYGON:
240         *out_generate = generate[out_idx][in_pv][out_pv][prim];
241         *out_prim = PIPE_PRIM_TRIANGLES;
242         *out_nr = (nr - 2) * 3;
243         return U_GENERATE_REUSABLE;
244
245      default:
246         assert(0);
247         *out_generate = generate[out_idx][in_pv][out_pv][PIPE_PRIM_POINTS];
248         *out_prim = PIPE_PRIM_POINTS;
249         *out_nr = nr;
250         return U_TRANSLATE_ERROR;
251      }
252   }
253}
254