1 /**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 /*
29 * Authors:
30 * Keith Whitwell <keith@tungstengraphics.com>
31 */
32
33 #include "util/u_memory.h"
34 #include "util/u_format.h"
35 #include "util/u_half.h"
36 #include "util/u_math.h"
37 #include "pipe/p_state.h"
38 #include "translate.h"
39
40
41 #define DRAW_DBG 0
42
43 typedef void (*fetch_func)(void *dst,
44 const uint8_t *src,
45 unsigned i, unsigned j);
46 typedef void (*emit_func)(const void *attrib, void *ptr);
47
48
49
50 struct translate_generic {
51 struct translate translate;
52
53 struct {
54 enum translate_element_type type;
55
56 fetch_func fetch;
57 unsigned buffer;
58 unsigned input_offset;
59 unsigned instance_divisor;
60
61 emit_func emit;
62 unsigned output_offset;
63
64 const uint8_t *input_ptr;
65 unsigned input_stride;
66 unsigned max_index;
67
68 /* this value is set to -1 if this is a normal element with output_format != input_format:
69 * in this case, u_format is used to do a full conversion
70 *
71 * this value is set to the format size in bytes if output_format == input_format or for 32-bit instance ids:
72 * in this case, memcpy is used to copy this amount of bytes
73 */
74 int copy_size;
75
76 } attrib[PIPE_MAX_ATTRIBS];
77
78 unsigned nr_attrib;
79 };
80
81
translate_generic(struct translate * translate)82 static struct translate_generic *translate_generic( struct translate *translate )
83 {
84 return (struct translate_generic *)translate;
85 }
86
87 /**
88 * Fetch a dword[4] vertex attribute from memory, doing format/type
89 * conversion as needed.
90 *
91 * This is probably needed/dupliocated elsewhere, eg format
92 * conversion, texture sampling etc.
93 */
94 #define ATTRIB( NAME, SZ, SRCTYPE, DSTTYPE, TO ) \
95 static void \
96 emit_##NAME(const void *attrib, void *ptr) \
97 { \
98 unsigned i; \
99 SRCTYPE *in = (SRCTYPE *)attrib; \
100 DSTTYPE *out = (DSTTYPE *)ptr; \
101 \
102 for (i = 0; i < SZ; i++) { \
103 out[i] = TO(in[i]); \
104 } \
105 }
106
107
108 #define TO_64_FLOAT(x) ((double) x)
109 #define TO_32_FLOAT(x) (x)
110 #define TO_16_FLOAT(x) util_float_to_half(x)
111
112 #define TO_8_USCALED(x) ((unsigned char) x)
113 #define TO_16_USCALED(x) ((unsigned short) x)
114 #define TO_32_USCALED(x) ((unsigned int) x)
115
116 #define TO_8_SSCALED(x) ((char) x)
117 #define TO_16_SSCALED(x) ((short) x)
118 #define TO_32_SSCALED(x) ((int) x)
119
120 #define TO_8_UNORM(x) ((unsigned char) (x * 255.0f))
121 #define TO_16_UNORM(x) ((unsigned short) (x * 65535.0f))
122 #define TO_32_UNORM(x) ((unsigned int) (x * 4294967295.0f))
123
124 #define TO_8_SNORM(x) ((char) (x * 127.0f))
125 #define TO_16_SNORM(x) ((short) (x * 32767.0f))
126 #define TO_32_SNORM(x) ((int) (x * 2147483647.0f))
127
128 #define TO_32_FIXED(x) ((int) (x * 65536.0f))
129
130 #define TO_INT(x) (x)
131
132
133 ATTRIB( R64G64B64A64_FLOAT, 4, float, double, TO_64_FLOAT )
134 ATTRIB( R64G64B64_FLOAT, 3, float, double, TO_64_FLOAT )
135 ATTRIB( R64G64_FLOAT, 2, float, double, TO_64_FLOAT )
136 ATTRIB( R64_FLOAT, 1, float, double, TO_64_FLOAT )
137
138 ATTRIB( R32G32B32A32_FLOAT, 4, float, float, TO_32_FLOAT )
139 ATTRIB( R32G32B32_FLOAT, 3, float, float, TO_32_FLOAT )
140 ATTRIB( R32G32_FLOAT, 2, float, float, TO_32_FLOAT )
141 ATTRIB( R32_FLOAT, 1, float, float, TO_32_FLOAT )
142
143 ATTRIB( R16G16B16A16_FLOAT, 4, float, ushort, TO_16_FLOAT )
144 ATTRIB( R16G16B16_FLOAT, 3, float, ushort, TO_16_FLOAT )
145 ATTRIB( R16G16_FLOAT, 2, float, ushort, TO_16_FLOAT )
146 ATTRIB( R16_FLOAT, 1, float, ushort, TO_16_FLOAT )
147
148 ATTRIB( R32G32B32A32_USCALED, 4, float, unsigned, TO_32_USCALED )
149 ATTRIB( R32G32B32_USCALED, 3, float, unsigned, TO_32_USCALED )
150 ATTRIB( R32G32_USCALED, 2, float, unsigned, TO_32_USCALED )
151 ATTRIB( R32_USCALED, 1, float, unsigned, TO_32_USCALED )
152
153 ATTRIB( R32G32B32A32_SSCALED, 4, float, int, TO_32_SSCALED )
154 ATTRIB( R32G32B32_SSCALED, 3, float, int, TO_32_SSCALED )
155 ATTRIB( R32G32_SSCALED, 2, float, int, TO_32_SSCALED )
156 ATTRIB( R32_SSCALED, 1, float, int, TO_32_SSCALED )
157
158 ATTRIB( R32G32B32A32_UNORM, 4, float, unsigned, TO_32_UNORM )
159 ATTRIB( R32G32B32_UNORM, 3, float, unsigned, TO_32_UNORM )
160 ATTRIB( R32G32_UNORM, 2, float, unsigned, TO_32_UNORM )
161 ATTRIB( R32_UNORM, 1, float, unsigned, TO_32_UNORM )
162
163 ATTRIB( R32G32B32A32_SNORM, 4, float, int, TO_32_SNORM )
164 ATTRIB( R32G32B32_SNORM, 3, float, int, TO_32_SNORM )
165 ATTRIB( R32G32_SNORM, 2, float, int, TO_32_SNORM )
166 ATTRIB( R32_SNORM, 1, float, int, TO_32_SNORM )
167
168 ATTRIB( R16G16B16A16_USCALED, 4, float, ushort, TO_16_USCALED )
169 ATTRIB( R16G16B16_USCALED, 3, float, ushort, TO_16_USCALED )
170 ATTRIB( R16G16_USCALED, 2, float, ushort, TO_16_USCALED )
171 ATTRIB( R16_USCALED, 1, float, ushort, TO_16_USCALED )
172
173 ATTRIB( R16G16B16A16_SSCALED, 4, float, short, TO_16_SSCALED )
174 ATTRIB( R16G16B16_SSCALED, 3, float, short, TO_16_SSCALED )
175 ATTRIB( R16G16_SSCALED, 2, float, short, TO_16_SSCALED )
176 ATTRIB( R16_SSCALED, 1, float, short, TO_16_SSCALED )
177
178 ATTRIB( R16G16B16A16_UNORM, 4, float, ushort, TO_16_UNORM )
179 ATTRIB( R16G16B16_UNORM, 3, float, ushort, TO_16_UNORM )
180 ATTRIB( R16G16_UNORM, 2, float, ushort, TO_16_UNORM )
181 ATTRIB( R16_UNORM, 1, float, ushort, TO_16_UNORM )
182
183 ATTRIB( R16G16B16A16_SNORM, 4, float, short, TO_16_SNORM )
184 ATTRIB( R16G16B16_SNORM, 3, float, short, TO_16_SNORM )
185 ATTRIB( R16G16_SNORM, 2, float, short, TO_16_SNORM )
186 ATTRIB( R16_SNORM, 1, float, short, TO_16_SNORM )
187
188 ATTRIB( R8G8B8A8_USCALED, 4, float, ubyte, TO_8_USCALED )
189 ATTRIB( R8G8B8_USCALED, 3, float, ubyte, TO_8_USCALED )
190 ATTRIB( R8G8_USCALED, 2, float, ubyte, TO_8_USCALED )
191 ATTRIB( R8_USCALED, 1, float, ubyte, TO_8_USCALED )
192
193 ATTRIB( R8G8B8A8_SSCALED, 4, float, char, TO_8_SSCALED )
194 ATTRIB( R8G8B8_SSCALED, 3, float, char, TO_8_SSCALED )
195 ATTRIB( R8G8_SSCALED, 2, float, char, TO_8_SSCALED )
196 ATTRIB( R8_SSCALED, 1, float, char, TO_8_SSCALED )
197
198 ATTRIB( R8G8B8A8_UNORM, 4, float, ubyte, TO_8_UNORM )
199 ATTRIB( R8G8B8_UNORM, 3, float, ubyte, TO_8_UNORM )
200 ATTRIB( R8G8_UNORM, 2, float, ubyte, TO_8_UNORM )
201 ATTRIB( R8_UNORM, 1, float, ubyte, TO_8_UNORM )
202
203 ATTRIB( R8G8B8A8_SNORM, 4, float, char, TO_8_SNORM )
204 ATTRIB( R8G8B8_SNORM, 3, float, char, TO_8_SNORM )
205 ATTRIB( R8G8_SNORM, 2, float, char, TO_8_SNORM )
206 ATTRIB( R8_SNORM, 1, float, char, TO_8_SNORM )
207
208 ATTRIB( R32G32B32A32_UINT, 4, uint32_t, unsigned, TO_INT )
209 ATTRIB( R32G32B32_UINT, 3, uint32_t, unsigned, TO_INT )
210 ATTRIB( R32G32_UINT, 2, uint32_t, unsigned, TO_INT )
211 ATTRIB( R32_UINT, 1, uint32_t, unsigned, TO_INT )
212
213 ATTRIB( R16G16B16A16_UINT, 4, uint32_t, ushort, TO_INT )
214 ATTRIB( R16G16B16_UINT, 3, uint32_t, ushort, TO_INT )
215 ATTRIB( R16G16_UINT, 2, uint32_t, ushort, TO_INT )
216 ATTRIB( R16_UINT, 1, uint32_t, ushort, TO_INT )
217
218 ATTRIB( R8G8B8A8_UINT, 4, uint32_t, ubyte, TO_INT )
219 ATTRIB( R8G8B8_UINT, 3, uint32_t, ubyte, TO_INT )
220 ATTRIB( R8G8_UINT, 2, uint32_t, ubyte, TO_INT )
221 ATTRIB( R8_UINT, 1, uint32_t, ubyte, TO_INT )
222
223 ATTRIB( R32G32B32A32_SINT, 4, int32_t, int, TO_INT )
224 ATTRIB( R32G32B32_SINT, 3, int32_t, int, TO_INT )
225 ATTRIB( R32G32_SINT, 2, int32_t, int, TO_INT )
226 ATTRIB( R32_SINT, 1, int32_t, int, TO_INT )
227
228 ATTRIB( R16G16B16A16_SINT, 4, int32_t, short, TO_INT )
229 ATTRIB( R16G16B16_SINT, 3, int32_t, short, TO_INT )
230 ATTRIB( R16G16_SINT, 2, int32_t, short, TO_INT )
231 ATTRIB( R16_SINT, 1, int32_t, short, TO_INT )
232
233 ATTRIB( R8G8B8A8_SINT, 4, int32_t, char, TO_INT )
234 ATTRIB( R8G8B8_SINT, 3, int32_t, char, TO_INT )
235 ATTRIB( R8G8_SINT, 2, int32_t, char, TO_INT )
236 ATTRIB( R8_SINT, 1, int32_t, char, TO_INT )
237
238 static void
emit_A8R8G8B8_UNORM(const void * attrib,void * ptr)239 emit_A8R8G8B8_UNORM( const void *attrib, void *ptr)
240 {
241 float *in = (float *)attrib;
242 ubyte *out = (ubyte *)ptr;
243 out[0] = TO_8_UNORM(in[3]);
244 out[1] = TO_8_UNORM(in[0]);
245 out[2] = TO_8_UNORM(in[1]);
246 out[3] = TO_8_UNORM(in[2]);
247 }
248
249 static void
emit_B8G8R8A8_UNORM(const void * attrib,void * ptr)250 emit_B8G8R8A8_UNORM( const void *attrib, void *ptr)
251 {
252 float *in = (float *)attrib;
253 ubyte *out = (ubyte *)ptr;
254 out[2] = TO_8_UNORM(in[0]);
255 out[1] = TO_8_UNORM(in[1]);
256 out[0] = TO_8_UNORM(in[2]);
257 out[3] = TO_8_UNORM(in[3]);
258 }
259
260 static void
emit_B10G10R10A2_UNORM(const void * attrib,void * ptr)261 emit_B10G10R10A2_UNORM( const void *attrib, void *ptr )
262 {
263 float *src = (float *)ptr;
264 uint32_t value = 0;
265 value |= ((uint32_t)(CLAMP(src[2], 0, 1) * 0x3ff)) & 0x3ff;
266 value |= (((uint32_t)(CLAMP(src[1], 0, 1) * 0x3ff)) & 0x3ff) << 10;
267 value |= (((uint32_t)(CLAMP(src[0], 0, 1) * 0x3ff)) & 0x3ff) << 20;
268 value |= ((uint32_t)(CLAMP(src[3], 0, 1) * 0x3)) << 30;
269 #ifdef PIPE_ARCH_BIG_ENDIAN
270 value = util_bswap32(value);
271 #endif
272 *(uint32_t *)attrib = value;
273 }
274
275 static void
emit_B10G10R10A2_USCALED(const void * attrib,void * ptr)276 emit_B10G10R10A2_USCALED( const void *attrib, void *ptr )
277 {
278 float *src = (float *)ptr;
279 uint32_t value = 0;
280 value |= ((uint32_t)CLAMP(src[2], 0, 1023)) & 0x3ff;
281 value |= (((uint32_t)CLAMP(src[1], 0, 1023)) & 0x3ff) << 10;
282 value |= (((uint32_t)CLAMP(src[0], 0, 1023)) & 0x3ff) << 20;
283 value |= ((uint32_t)CLAMP(src[3], 0, 3)) << 30;
284 #ifdef PIPE_ARCH_BIG_ENDIAN
285 value = util_bswap32(value);
286 #endif
287 *(uint32_t *)attrib = value;
288 }
289
290 static void
emit_B10G10R10A2_SNORM(const void * attrib,void * ptr)291 emit_B10G10R10A2_SNORM( const void *attrib, void *ptr )
292 {
293 float *src = (float *)ptr;
294 uint32_t value = 0;
295 value |= (uint32_t)(((uint32_t)(CLAMP(src[2], -1, 1) * 0x1ff)) & 0x3ff) ;
296 value |= (uint32_t)((((uint32_t)(CLAMP(src[1], -1, 1) * 0x1ff)) & 0x3ff) << 10) ;
297 value |= (uint32_t)((((uint32_t)(CLAMP(src[0], -1, 1) * 0x1ff)) & 0x3ff) << 20) ;
298 value |= (uint32_t)(((uint32_t)(CLAMP(src[3], -1, 1) * 0x1)) << 30) ;
299 #ifdef PIPE_ARCH_BIG_ENDIAN
300 value = util_bswap32(value);
301 #endif
302 *(uint32_t *)attrib = value;
303 }
304
305 static void
emit_B10G10R10A2_SSCALED(const void * attrib,void * ptr)306 emit_B10G10R10A2_SSCALED( const void *attrib, void *ptr )
307 {
308 float *src = (float *)ptr;
309 uint32_t value = 0;
310 value |= (uint32_t)(((uint32_t)CLAMP(src[2], -512, 511)) & 0x3ff) ;
311 value |= (uint32_t)((((uint32_t)CLAMP(src[1], -512, 511)) & 0x3ff) << 10) ;
312 value |= (uint32_t)((((uint32_t)CLAMP(src[0], -512, 511)) & 0x3ff) << 20) ;
313 value |= (uint32_t)(((uint32_t)CLAMP(src[3], -2, 1)) << 30) ;
314 #ifdef PIPE_ARCH_BIG_ENDIAN
315 value = util_bswap32(value);
316 #endif
317 *(uint32_t *)attrib = value;
318 }
319
320 static void
emit_R10G10B10A2_UNORM(const void * attrib,void * ptr)321 emit_R10G10B10A2_UNORM( const void *attrib, void *ptr )
322 {
323 float *src = (float *)ptr;
324 uint32_t value = 0;
325 value |= ((uint32_t)(CLAMP(src[0], 0, 1) * 0x3ff)) & 0x3ff;
326 value |= (((uint32_t)(CLAMP(src[1], 0, 1) * 0x3ff)) & 0x3ff) << 10;
327 value |= (((uint32_t)(CLAMP(src[2], 0, 1) * 0x3ff)) & 0x3ff) << 20;
328 value |= ((uint32_t)(CLAMP(src[3], 0, 1) * 0x3)) << 30;
329 #ifdef PIPE_ARCH_BIG_ENDIAN
330 value = util_bswap32(value);
331 #endif
332 *(uint32_t *)attrib = value;
333 }
334
335 static void
emit_R10G10B10A2_USCALED(const void * attrib,void * ptr)336 emit_R10G10B10A2_USCALED( const void *attrib, void *ptr )
337 {
338 float *src = (float *)ptr;
339 uint32_t value = 0;
340 value |= ((uint32_t)CLAMP(src[0], 0, 1023)) & 0x3ff;
341 value |= (((uint32_t)CLAMP(src[1], 0, 1023)) & 0x3ff) << 10;
342 value |= (((uint32_t)CLAMP(src[2], 0, 1023)) & 0x3ff) << 20;
343 value |= ((uint32_t)CLAMP(src[3], 0, 3)) << 30;
344 #ifdef PIPE_ARCH_BIG_ENDIAN
345 value = util_bswap32(value);
346 #endif
347 *(uint32_t *)attrib = value;
348 }
349
350 static void
emit_R10G10B10A2_SNORM(const void * attrib,void * ptr)351 emit_R10G10B10A2_SNORM( const void *attrib, void *ptr )
352 {
353 float *src = (float *)ptr;
354 uint32_t value = 0;
355 value |= (uint32_t)(((uint32_t)(CLAMP(src[0], -1, 1) * 0x1ff)) & 0x3ff) ;
356 value |= (uint32_t)((((uint32_t)(CLAMP(src[1], -1, 1) * 0x1ff)) & 0x3ff) << 10) ;
357 value |= (uint32_t)((((uint32_t)(CLAMP(src[2], -1, 1) * 0x1ff)) & 0x3ff) << 20) ;
358 value |= (uint32_t)(((uint32_t)(CLAMP(src[3], -1, 1) * 0x1)) << 30) ;
359 #ifdef PIPE_ARCH_BIG_ENDIAN
360 value = util_bswap32(value);
361 #endif
362 *(uint32_t *)attrib = value;
363 }
364
365 static void
emit_R10G10B10A2_SSCALED(const void * attrib,void * ptr)366 emit_R10G10B10A2_SSCALED( const void *attrib, void *ptr)
367 {
368 float *src = (float *)ptr;
369 uint32_t value = 0;
370 value |= (uint32_t)(((uint32_t)CLAMP(src[0], -512, 511)) & 0x3ff) ;
371 value |= (uint32_t)((((uint32_t)CLAMP(src[1], -512, 511)) & 0x3ff) << 10) ;
372 value |= (uint32_t)((((uint32_t)CLAMP(src[2], -512, 511)) & 0x3ff) << 20) ;
373 value |= (uint32_t)(((uint32_t)CLAMP(src[3], -2, 1)) << 30) ;
374 #ifdef PIPE_ARCH_BIG_ENDIAN
375 value = util_bswap32(value);
376 #endif
377 *(uint32_t *)attrib = value;
378 }
379
380 static void
emit_NULL(const void * attrib,void * ptr)381 emit_NULL( const void *attrib, void *ptr )
382 {
383 /* do nothing is the only sensible option */
384 }
385
get_emit_func(enum pipe_format format)386 static emit_func get_emit_func( enum pipe_format format )
387 {
388 switch (format) {
389 case PIPE_FORMAT_R64_FLOAT:
390 return &emit_R64_FLOAT;
391 case PIPE_FORMAT_R64G64_FLOAT:
392 return &emit_R64G64_FLOAT;
393 case PIPE_FORMAT_R64G64B64_FLOAT:
394 return &emit_R64G64B64_FLOAT;
395 case PIPE_FORMAT_R64G64B64A64_FLOAT:
396 return &emit_R64G64B64A64_FLOAT;
397
398 case PIPE_FORMAT_R32_FLOAT:
399 return &emit_R32_FLOAT;
400 case PIPE_FORMAT_R32G32_FLOAT:
401 return &emit_R32G32_FLOAT;
402 case PIPE_FORMAT_R32G32B32_FLOAT:
403 return &emit_R32G32B32_FLOAT;
404 case PIPE_FORMAT_R32G32B32A32_FLOAT:
405 return &emit_R32G32B32A32_FLOAT;
406
407 case PIPE_FORMAT_R16_FLOAT:
408 return &emit_R16_FLOAT;
409 case PIPE_FORMAT_R16G16_FLOAT:
410 return &emit_R16G16_FLOAT;
411 case PIPE_FORMAT_R16G16B16_FLOAT:
412 return &emit_R16G16B16_FLOAT;
413 case PIPE_FORMAT_R16G16B16A16_FLOAT:
414 return &emit_R16G16B16A16_FLOAT;
415
416 case PIPE_FORMAT_R32_UNORM:
417 return &emit_R32_UNORM;
418 case PIPE_FORMAT_R32G32_UNORM:
419 return &emit_R32G32_UNORM;
420 case PIPE_FORMAT_R32G32B32_UNORM:
421 return &emit_R32G32B32_UNORM;
422 case PIPE_FORMAT_R32G32B32A32_UNORM:
423 return &emit_R32G32B32A32_UNORM;
424
425 case PIPE_FORMAT_R32_USCALED:
426 return &emit_R32_USCALED;
427 case PIPE_FORMAT_R32G32_USCALED:
428 return &emit_R32G32_USCALED;
429 case PIPE_FORMAT_R32G32B32_USCALED:
430 return &emit_R32G32B32_USCALED;
431 case PIPE_FORMAT_R32G32B32A32_USCALED:
432 return &emit_R32G32B32A32_USCALED;
433
434 case PIPE_FORMAT_R32_SNORM:
435 return &emit_R32_SNORM;
436 case PIPE_FORMAT_R32G32_SNORM:
437 return &emit_R32G32_SNORM;
438 case PIPE_FORMAT_R32G32B32_SNORM:
439 return &emit_R32G32B32_SNORM;
440 case PIPE_FORMAT_R32G32B32A32_SNORM:
441 return &emit_R32G32B32A32_SNORM;
442
443 case PIPE_FORMAT_R32_SSCALED:
444 return &emit_R32_SSCALED;
445 case PIPE_FORMAT_R32G32_SSCALED:
446 return &emit_R32G32_SSCALED;
447 case PIPE_FORMAT_R32G32B32_SSCALED:
448 return &emit_R32G32B32_SSCALED;
449 case PIPE_FORMAT_R32G32B32A32_SSCALED:
450 return &emit_R32G32B32A32_SSCALED;
451
452 case PIPE_FORMAT_R16_UNORM:
453 return &emit_R16_UNORM;
454 case PIPE_FORMAT_R16G16_UNORM:
455 return &emit_R16G16_UNORM;
456 case PIPE_FORMAT_R16G16B16_UNORM:
457 return &emit_R16G16B16_UNORM;
458 case PIPE_FORMAT_R16G16B16A16_UNORM:
459 return &emit_R16G16B16A16_UNORM;
460
461 case PIPE_FORMAT_R16_USCALED:
462 return &emit_R16_USCALED;
463 case PIPE_FORMAT_R16G16_USCALED:
464 return &emit_R16G16_USCALED;
465 case PIPE_FORMAT_R16G16B16_USCALED:
466 return &emit_R16G16B16_USCALED;
467 case PIPE_FORMAT_R16G16B16A16_USCALED:
468 return &emit_R16G16B16A16_USCALED;
469
470 case PIPE_FORMAT_R16_SNORM:
471 return &emit_R16_SNORM;
472 case PIPE_FORMAT_R16G16_SNORM:
473 return &emit_R16G16_SNORM;
474 case PIPE_FORMAT_R16G16B16_SNORM:
475 return &emit_R16G16B16_SNORM;
476 case PIPE_FORMAT_R16G16B16A16_SNORM:
477 return &emit_R16G16B16A16_SNORM;
478
479 case PIPE_FORMAT_R16_SSCALED:
480 return &emit_R16_SSCALED;
481 case PIPE_FORMAT_R16G16_SSCALED:
482 return &emit_R16G16_SSCALED;
483 case PIPE_FORMAT_R16G16B16_SSCALED:
484 return &emit_R16G16B16_SSCALED;
485 case PIPE_FORMAT_R16G16B16A16_SSCALED:
486 return &emit_R16G16B16A16_SSCALED;
487
488 case PIPE_FORMAT_R8_UNORM:
489 return &emit_R8_UNORM;
490 case PIPE_FORMAT_R8G8_UNORM:
491 return &emit_R8G8_UNORM;
492 case PIPE_FORMAT_R8G8B8_UNORM:
493 return &emit_R8G8B8_UNORM;
494 case PIPE_FORMAT_R8G8B8A8_UNORM:
495 return &emit_R8G8B8A8_UNORM;
496
497 case PIPE_FORMAT_R8_USCALED:
498 return &emit_R8_USCALED;
499 case PIPE_FORMAT_R8G8_USCALED:
500 return &emit_R8G8_USCALED;
501 case PIPE_FORMAT_R8G8B8_USCALED:
502 return &emit_R8G8B8_USCALED;
503 case PIPE_FORMAT_R8G8B8A8_USCALED:
504 return &emit_R8G8B8A8_USCALED;
505
506 case PIPE_FORMAT_R8_SNORM:
507 return &emit_R8_SNORM;
508 case PIPE_FORMAT_R8G8_SNORM:
509 return &emit_R8G8_SNORM;
510 case PIPE_FORMAT_R8G8B8_SNORM:
511 return &emit_R8G8B8_SNORM;
512 case PIPE_FORMAT_R8G8B8A8_SNORM:
513 return &emit_R8G8B8A8_SNORM;
514
515 case PIPE_FORMAT_R8_SSCALED:
516 return &emit_R8_SSCALED;
517 case PIPE_FORMAT_R8G8_SSCALED:
518 return &emit_R8G8_SSCALED;
519 case PIPE_FORMAT_R8G8B8_SSCALED:
520 return &emit_R8G8B8_SSCALED;
521 case PIPE_FORMAT_R8G8B8A8_SSCALED:
522 return &emit_R8G8B8A8_SSCALED;
523
524 case PIPE_FORMAT_B8G8R8A8_UNORM:
525 return &emit_B8G8R8A8_UNORM;
526
527 case PIPE_FORMAT_A8R8G8B8_UNORM:
528 return &emit_A8R8G8B8_UNORM;
529
530 case PIPE_FORMAT_R32_UINT:
531 return &emit_R32_UINT;
532 case PIPE_FORMAT_R32G32_UINT:
533 return &emit_R32G32_UINT;
534 case PIPE_FORMAT_R32G32B32_UINT:
535 return &emit_R32G32B32_UINT;
536 case PIPE_FORMAT_R32G32B32A32_UINT:
537 return &emit_R32G32B32A32_UINT;
538
539 case PIPE_FORMAT_R16_UINT:
540 return &emit_R16_UINT;
541 case PIPE_FORMAT_R16G16_UINT:
542 return &emit_R16G16_UINT;
543 case PIPE_FORMAT_R16G16B16_UINT:
544 return &emit_R16G16B16_UINT;
545 case PIPE_FORMAT_R16G16B16A16_UINT:
546 return &emit_R16G16B16A16_UINT;
547
548 case PIPE_FORMAT_R8_UINT:
549 return &emit_R8_UINT;
550 case PIPE_FORMAT_R8G8_UINT:
551 return &emit_R8G8_UINT;
552 case PIPE_FORMAT_R8G8B8_UINT:
553 return &emit_R8G8B8_UINT;
554 case PIPE_FORMAT_R8G8B8A8_UINT:
555 return &emit_R8G8B8A8_UINT;
556
557 case PIPE_FORMAT_R32_SINT:
558 return &emit_R32_SINT;
559 case PIPE_FORMAT_R32G32_SINT:
560 return &emit_R32G32_SINT;
561 case PIPE_FORMAT_R32G32B32_SINT:
562 return &emit_R32G32B32_SINT;
563 case PIPE_FORMAT_R32G32B32A32_SINT:
564 return &emit_R32G32B32A32_SINT;
565
566 case PIPE_FORMAT_R16_SINT:
567 return &emit_R16_SINT;
568 case PIPE_FORMAT_R16G16_SINT:
569 return &emit_R16G16_SINT;
570 case PIPE_FORMAT_R16G16B16_SINT:
571 return &emit_R16G16B16_SINT;
572 case PIPE_FORMAT_R16G16B16A16_SINT:
573 return &emit_R16G16B16A16_SINT;
574
575 case PIPE_FORMAT_R8_SINT:
576 return &emit_R8_SINT;
577 case PIPE_FORMAT_R8G8_SINT:
578 return &emit_R8G8_SINT;
579 case PIPE_FORMAT_R8G8B8_SINT:
580 return &emit_R8G8B8_SINT;
581 case PIPE_FORMAT_R8G8B8A8_SINT:
582 return &emit_R8G8B8A8_SINT;
583
584 case PIPE_FORMAT_B10G10R10A2_UNORM:
585 return &emit_B10G10R10A2_UNORM;
586 case PIPE_FORMAT_B10G10R10A2_USCALED:
587 return &emit_B10G10R10A2_USCALED;
588 case PIPE_FORMAT_B10G10R10A2_SNORM:
589 return &emit_B10G10R10A2_SNORM;
590 case PIPE_FORMAT_B10G10R10A2_SSCALED:
591 return &emit_B10G10R10A2_SSCALED;
592
593 case PIPE_FORMAT_R10G10B10A2_UNORM:
594 return &emit_R10G10B10A2_UNORM;
595 case PIPE_FORMAT_R10G10B10A2_USCALED:
596 return &emit_R10G10B10A2_USCALED;
597 case PIPE_FORMAT_R10G10B10A2_SNORM:
598 return &emit_R10G10B10A2_SNORM;
599 case PIPE_FORMAT_R10G10B10A2_SSCALED:
600 return &emit_R10G10B10A2_SSCALED;
601
602 default:
603 assert(0);
604 return &emit_NULL;
605 }
606 }
607
generic_run_one(struct translate_generic * tg,unsigned elt,unsigned instance_id,void * vert)608 static ALWAYS_INLINE void PIPE_CDECL generic_run_one( struct translate_generic *tg,
609 unsigned elt,
610 unsigned instance_id,
611 void *vert )
612 {
613 unsigned nr_attrs = tg->nr_attrib;
614 unsigned attr;
615
616 for (attr = 0; attr < nr_attrs; attr++) {
617 float data[4];
618 uint8_t *dst = (uint8_t *)vert + tg->attrib[attr].output_offset;
619
620 if (tg->attrib[attr].type == TRANSLATE_ELEMENT_NORMAL) {
621 const uint8_t *src;
622 unsigned index;
623 int copy_size;
624
625 if (tg->attrib[attr].instance_divisor) {
626 index = instance_id / tg->attrib[attr].instance_divisor;
627 /* XXX we need to clamp the index here too, but to a
628 * per-array max value, not the draw->pt.max_index value
629 * that's being given to us via translate->set_buffer().
630 */
631 }
632 else {
633 index = elt;
634 /* clamp to avoid going out of bounds */
635 index = MIN2(index, tg->attrib[attr].max_index);
636 }
637
638 src = tg->attrib[attr].input_ptr +
639 tg->attrib[attr].input_stride * index;
640
641 copy_size = tg->attrib[attr].copy_size;
642 if(likely(copy_size >= 0))
643 memcpy(dst, src, copy_size);
644 else
645 {
646 tg->attrib[attr].fetch( data, src, 0, 0 );
647
648 if (0)
649 debug_printf("Fetch linear attr %d from %p stride %d index %d: "
650 " %f, %f, %f, %f \n",
651 attr,
652 tg->attrib[attr].input_ptr,
653 tg->attrib[attr].input_stride,
654 index,
655 data[0], data[1],data[2], data[3]);
656
657 tg->attrib[attr].emit( data, dst );
658 }
659 } else {
660 if(likely(tg->attrib[attr].copy_size >= 0))
661 memcpy(data, &instance_id, 4);
662 else
663 {
664 data[0] = (float)instance_id;
665 tg->attrib[attr].emit( data, dst );
666 }
667 }
668 }
669 }
670
671 /**
672 * Fetch vertex attributes for 'count' vertices.
673 */
generic_run_elts(struct translate * translate,const unsigned * elts,unsigned count,unsigned instance_id,void * output_buffer)674 static void PIPE_CDECL generic_run_elts( struct translate *translate,
675 const unsigned *elts,
676 unsigned count,
677 unsigned instance_id,
678 void *output_buffer )
679 {
680 struct translate_generic *tg = translate_generic(translate);
681 char *vert = output_buffer;
682 unsigned i;
683
684 for (i = 0; i < count; i++) {
685 generic_run_one(tg, *elts++, instance_id, vert);
686 vert += tg->translate.key.output_stride;
687 }
688 }
689
generic_run_elts16(struct translate * translate,const uint16_t * elts,unsigned count,unsigned instance_id,void * output_buffer)690 static void PIPE_CDECL generic_run_elts16( struct translate *translate,
691 const uint16_t *elts,
692 unsigned count,
693 unsigned instance_id,
694 void *output_buffer )
695 {
696 struct translate_generic *tg = translate_generic(translate);
697 char *vert = output_buffer;
698 unsigned i;
699
700 for (i = 0; i < count; i++) {
701 generic_run_one(tg, *elts++, instance_id, vert);
702 vert += tg->translate.key.output_stride;
703 }
704 }
705
generic_run_elts8(struct translate * translate,const uint8_t * elts,unsigned count,unsigned instance_id,void * output_buffer)706 static void PIPE_CDECL generic_run_elts8( struct translate *translate,
707 const uint8_t *elts,
708 unsigned count,
709 unsigned instance_id,
710 void *output_buffer )
711 {
712 struct translate_generic *tg = translate_generic(translate);
713 char *vert = output_buffer;
714 unsigned i;
715
716 for (i = 0; i < count; i++) {
717 generic_run_one(tg, *elts++, instance_id, vert);
718 vert += tg->translate.key.output_stride;
719 }
720 }
721
generic_run(struct translate * translate,unsigned start,unsigned count,unsigned instance_id,void * output_buffer)722 static void PIPE_CDECL generic_run( struct translate *translate,
723 unsigned start,
724 unsigned count,
725 unsigned instance_id,
726 void *output_buffer )
727 {
728 struct translate_generic *tg = translate_generic(translate);
729 char *vert = output_buffer;
730 unsigned i;
731
732 for (i = 0; i < count; i++) {
733 generic_run_one(tg, start + i, instance_id, vert);
734 vert += tg->translate.key.output_stride;
735 }
736 }
737
738
739
generic_set_buffer(struct translate * translate,unsigned buf,const void * ptr,unsigned stride,unsigned max_index)740 static void generic_set_buffer( struct translate *translate,
741 unsigned buf,
742 const void *ptr,
743 unsigned stride,
744 unsigned max_index )
745 {
746 struct translate_generic *tg = translate_generic(translate);
747 unsigned i;
748
749 for (i = 0; i < tg->nr_attrib; i++) {
750 if (tg->attrib[i].buffer == buf) {
751 tg->attrib[i].input_ptr = ((const uint8_t *)ptr +
752 tg->attrib[i].input_offset);
753 tg->attrib[i].input_stride = stride;
754 tg->attrib[i].max_index = max_index;
755 }
756 }
757 }
758
759
generic_release(struct translate * translate)760 static void generic_release( struct translate *translate )
761 {
762 /* Refcount?
763 */
764 FREE(translate);
765 }
766
767 static boolean
is_legal_int_format_combo(const struct util_format_description * src,const struct util_format_description * dst)768 is_legal_int_format_combo( const struct util_format_description *src,
769 const struct util_format_description *dst )
770 {
771 unsigned i;
772 unsigned nr = MIN2(src->nr_channels, dst->nr_channels);
773
774 for (i = 0; i < nr; i++) {
775 /* The signs must match. */
776 if (src->channel[i].type != dst->channel[i].type) {
777 return FALSE;
778 }
779
780 /* Integers must not lose precision at any point in the pipeline. */
781 if (src->channel[i].size > dst->channel[i].size) {
782 return FALSE;
783 }
784 }
785 return TRUE;
786 }
787
translate_generic_create(const struct translate_key * key)788 struct translate *translate_generic_create( const struct translate_key *key )
789 {
790 struct translate_generic *tg = CALLOC_STRUCT(translate_generic);
791 unsigned i;
792
793 if (tg == NULL)
794 return NULL;
795
796 tg->translate.key = *key;
797 tg->translate.release = generic_release;
798 tg->translate.set_buffer = generic_set_buffer;
799 tg->translate.run_elts = generic_run_elts;
800 tg->translate.run_elts16 = generic_run_elts16;
801 tg->translate.run_elts8 = generic_run_elts8;
802 tg->translate.run = generic_run;
803
804 for (i = 0; i < key->nr_elements; i++) {
805 const struct util_format_description *format_desc =
806 util_format_description(key->element[i].input_format);
807
808 assert(format_desc);
809 assert(format_desc->fetch_rgba_float);
810
811 tg->attrib[i].type = key->element[i].type;
812
813 if (format_desc->channel[0].pure_integer) {
814 const struct util_format_description *out_format_desc =
815 util_format_description(key->element[i].output_format);
816
817 if (!is_legal_int_format_combo(format_desc, out_format_desc)) {
818 FREE(tg);
819 return NULL;
820 }
821
822 if (format_desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED) {
823 tg->attrib[i].fetch = (fetch_func)format_desc->fetch_rgba_sint;
824 } else {
825 tg->attrib[i].fetch = (fetch_func)format_desc->fetch_rgba_uint;
826 }
827 } else {
828 tg->attrib[i].fetch = (fetch_func)format_desc->fetch_rgba_float;
829 }
830
831 tg->attrib[i].buffer = key->element[i].input_buffer;
832 tg->attrib[i].input_offset = key->element[i].input_offset;
833 tg->attrib[i].instance_divisor = key->element[i].instance_divisor;
834
835 tg->attrib[i].output_offset = key->element[i].output_offset;
836
837 tg->attrib[i].copy_size = -1;
838 if (tg->attrib[i].type == TRANSLATE_ELEMENT_INSTANCE_ID)
839 {
840 if(key->element[i].output_format == PIPE_FORMAT_R32_USCALED
841 || key->element[i].output_format == PIPE_FORMAT_R32_SSCALED)
842 tg->attrib[i].copy_size = 4;
843 }
844 else
845 {
846 if(key->element[i].input_format == key->element[i].output_format
847 && format_desc->block.width == 1
848 && format_desc->block.height == 1
849 && !(format_desc->block.bits & 7))
850 tg->attrib[i].copy_size = format_desc->block.bits >> 3;
851 }
852
853 if(tg->attrib[i].copy_size < 0)
854 tg->attrib[i].emit = get_emit_func(key->element[i].output_format);
855 else
856 tg->attrib[i].emit = NULL;
857 }
858
859 tg->nr_attrib = key->nr_elements;
860
861
862 return &tg->translate;
863 }
864
translate_generic_is_output_format_supported(enum pipe_format format)865 boolean translate_generic_is_output_format_supported(enum pipe_format format)
866 {
867 switch(format)
868 {
869 case PIPE_FORMAT_R64G64B64A64_FLOAT: return TRUE;
870 case PIPE_FORMAT_R64G64B64_FLOAT: return TRUE;
871 case PIPE_FORMAT_R64G64_FLOAT: return TRUE;
872 case PIPE_FORMAT_R64_FLOAT: return TRUE;
873
874 case PIPE_FORMAT_R32G32B32A32_FLOAT: return TRUE;
875 case PIPE_FORMAT_R32G32B32_FLOAT: return TRUE;
876 case PIPE_FORMAT_R32G32_FLOAT: return TRUE;
877 case PIPE_FORMAT_R32_FLOAT: return TRUE;
878
879 case PIPE_FORMAT_R16G16B16A16_FLOAT: return TRUE;
880 case PIPE_FORMAT_R16G16B16_FLOAT: return TRUE;
881 case PIPE_FORMAT_R16G16_FLOAT: return TRUE;
882 case PIPE_FORMAT_R16_FLOAT: return TRUE;
883
884 case PIPE_FORMAT_R32G32B32A32_USCALED: return TRUE;
885 case PIPE_FORMAT_R32G32B32_USCALED: return TRUE;
886 case PIPE_FORMAT_R32G32_USCALED: return TRUE;
887 case PIPE_FORMAT_R32_USCALED: return TRUE;
888
889 case PIPE_FORMAT_R32G32B32A32_SSCALED: return TRUE;
890 case PIPE_FORMAT_R32G32B32_SSCALED: return TRUE;
891 case PIPE_FORMAT_R32G32_SSCALED: return TRUE;
892 case PIPE_FORMAT_R32_SSCALED: return TRUE;
893
894 case PIPE_FORMAT_R32G32B32A32_UNORM: return TRUE;
895 case PIPE_FORMAT_R32G32B32_UNORM: return TRUE;
896 case PIPE_FORMAT_R32G32_UNORM: return TRUE;
897 case PIPE_FORMAT_R32_UNORM: return TRUE;
898
899 case PIPE_FORMAT_R32G32B32A32_SNORM: return TRUE;
900 case PIPE_FORMAT_R32G32B32_SNORM: return TRUE;
901 case PIPE_FORMAT_R32G32_SNORM: return TRUE;
902 case PIPE_FORMAT_R32_SNORM: return TRUE;
903
904 case PIPE_FORMAT_R16G16B16A16_USCALED: return TRUE;
905 case PIPE_FORMAT_R16G16B16_USCALED: return TRUE;
906 case PIPE_FORMAT_R16G16_USCALED: return TRUE;
907 case PIPE_FORMAT_R16_USCALED: return TRUE;
908
909 case PIPE_FORMAT_R16G16B16A16_SSCALED: return TRUE;
910 case PIPE_FORMAT_R16G16B16_SSCALED: return TRUE;
911 case PIPE_FORMAT_R16G16_SSCALED: return TRUE;
912 case PIPE_FORMAT_R16_SSCALED: return TRUE;
913
914 case PIPE_FORMAT_R16G16B16A16_UNORM: return TRUE;
915 case PIPE_FORMAT_R16G16B16_UNORM: return TRUE;
916 case PIPE_FORMAT_R16G16_UNORM: return TRUE;
917 case PIPE_FORMAT_R16_UNORM: return TRUE;
918
919 case PIPE_FORMAT_R16G16B16A16_SNORM: return TRUE;
920 case PIPE_FORMAT_R16G16B16_SNORM: return TRUE;
921 case PIPE_FORMAT_R16G16_SNORM: return TRUE;
922 case PIPE_FORMAT_R16_SNORM: return TRUE;
923
924 case PIPE_FORMAT_R8G8B8A8_USCALED: return TRUE;
925 case PIPE_FORMAT_R8G8B8_USCALED: return TRUE;
926 case PIPE_FORMAT_R8G8_USCALED: return TRUE;
927 case PIPE_FORMAT_R8_USCALED: return TRUE;
928
929 case PIPE_FORMAT_R8G8B8A8_SSCALED: return TRUE;
930 case PIPE_FORMAT_R8G8B8_SSCALED: return TRUE;
931 case PIPE_FORMAT_R8G8_SSCALED: return TRUE;
932 case PIPE_FORMAT_R8_SSCALED: return TRUE;
933
934 case PIPE_FORMAT_R8G8B8A8_UNORM: return TRUE;
935 case PIPE_FORMAT_R8G8B8_UNORM: return TRUE;
936 case PIPE_FORMAT_R8G8_UNORM: return TRUE;
937 case PIPE_FORMAT_R8_UNORM: return TRUE;
938
939 case PIPE_FORMAT_R8G8B8A8_SNORM: return TRUE;
940 case PIPE_FORMAT_R8G8B8_SNORM: return TRUE;
941 case PIPE_FORMAT_R8G8_SNORM: return TRUE;
942 case PIPE_FORMAT_R8_SNORM: return TRUE;
943
944 case PIPE_FORMAT_A8R8G8B8_UNORM: return TRUE;
945 case PIPE_FORMAT_B8G8R8A8_UNORM: return TRUE;
946
947 case PIPE_FORMAT_R32G32B32A32_UINT: return TRUE;
948 case PIPE_FORMAT_R32G32B32_UINT: return TRUE;
949 case PIPE_FORMAT_R32G32_UINT: return TRUE;
950 case PIPE_FORMAT_R32_UINT: return TRUE;
951
952 case PIPE_FORMAT_R16G16B16A16_UINT: return TRUE;
953 case PIPE_FORMAT_R16G16B16_UINT: return TRUE;
954 case PIPE_FORMAT_R16G16_UINT: return TRUE;
955 case PIPE_FORMAT_R16_UINT: return TRUE;
956
957 case PIPE_FORMAT_R8G8B8A8_UINT: return TRUE;
958 case PIPE_FORMAT_R8G8B8_UINT: return TRUE;
959 case PIPE_FORMAT_R8G8_UINT: return TRUE;
960 case PIPE_FORMAT_R8_UINT: return TRUE;
961
962 case PIPE_FORMAT_R32G32B32A32_SINT: return TRUE;
963 case PIPE_FORMAT_R32G32B32_SINT: return TRUE;
964 case PIPE_FORMAT_R32G32_SINT: return TRUE;
965 case PIPE_FORMAT_R32_SINT: return TRUE;
966
967 case PIPE_FORMAT_R16G16B16A16_SINT: return TRUE;
968 case PIPE_FORMAT_R16G16B16_SINT: return TRUE;
969 case PIPE_FORMAT_R16G16_SINT: return TRUE;
970 case PIPE_FORMAT_R16_SINT: return TRUE;
971
972 case PIPE_FORMAT_R8G8B8A8_SINT: return TRUE;
973 case PIPE_FORMAT_R8G8B8_SINT: return TRUE;
974 case PIPE_FORMAT_R8G8_SINT: return TRUE;
975 case PIPE_FORMAT_R8_SINT: return TRUE;
976
977 case PIPE_FORMAT_B10G10R10A2_UNORM: return TRUE;
978 case PIPE_FORMAT_B10G10R10A2_USCALED: return TRUE;
979 case PIPE_FORMAT_B10G10R10A2_SNORM: return TRUE;
980 case PIPE_FORMAT_B10G10R10A2_SSCALED: return TRUE;
981
982 case PIPE_FORMAT_R10G10B10A2_UNORM: return TRUE;
983 case PIPE_FORMAT_R10G10B10A2_USCALED: return TRUE;
984 case PIPE_FORMAT_R10G10B10A2_SNORM: return TRUE;
985 case PIPE_FORMAT_R10G10B10A2_SSCALED: return TRUE;
986
987 default: return FALSE;
988 }
989 }
990