Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 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<
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<
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
}