1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
30 * Keith Whitwell <keith@tungstengraphics.com>
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"
43 typedef void (*fetch_func
)(void *dst
,
45 unsigned i
, unsigned j
);
46 typedef void (*emit_func
)(const void *attrib
, void *ptr
);
50 struct translate_generic
{
51 struct translate translate
;
54 enum translate_element_type type
;
58 unsigned input_offset
;
59 unsigned instance_divisor
;
62 unsigned output_offset
;
64 const uint8_t *input_ptr
;
65 unsigned input_stride
;
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
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
76 } attrib
[PIPE_MAX_ATTRIBS
];
82 static struct translate_generic
*translate_generic( struct translate
*translate
)
84 return (struct translate_generic
*)translate
;
88 * Fetch a dword[4] vertex attribute from memory, doing format/type
89 * conversion as needed.
91 * This is probably needed/dupliocated elsewhere, eg format
92 * conversion, texture sampling etc.
94 #define ATTRIB( NAME, SZ, SRCTYPE, DSTTYPE, TO ) \
96 emit_##NAME(const void *attrib, void *ptr) \
99 SRCTYPE *in = (SRCTYPE *)attrib; \
100 DSTTYPE *out = (DSTTYPE *)ptr; \
102 for (i = 0; i < SZ; i++) { \
103 out[i] = TO(in[i]); \
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)
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)
116 #define TO_8_SSCALED(x) ((char) x)
117 #define TO_16_SSCALED(x) ((short) x)
118 #define TO_32_SSCALED(x) ((int) x)
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))
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))
128 #define TO_32_FIXED(x) ((int) (x * 65536.0f))
130 #define TO_INT(x) (x)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
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
)
239 emit_A8R8G8B8_UNORM( const void *attrib
, void *ptr
)
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]);
250 emit_B8G8R8A8_UNORM( const void *attrib
, void *ptr
)
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]);
261 emit_B10G10R10A2_UNORM( const void *attrib
, void *ptr
)
263 float *src
= (float *)ptr
;
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
);
272 *(uint32_t *)attrib
= value
;
276 emit_B10G10R10A2_USCALED( const void *attrib
, void *ptr
)
278 float *src
= (float *)ptr
;
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
);
287 *(uint32_t *)attrib
= value
;
291 emit_B10G10R10A2_SNORM( const void *attrib
, void *ptr
)
293 float *src
= (float *)ptr
;
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
);
302 *(uint32_t *)attrib
= value
;
306 emit_B10G10R10A2_SSCALED( const void *attrib
, void *ptr
)
308 float *src
= (float *)ptr
;
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
);
317 *(uint32_t *)attrib
= value
;
321 emit_R10G10B10A2_UNORM( const void *attrib
, void *ptr
)
323 float *src
= (float *)ptr
;
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
);
332 *(uint32_t *)attrib
= value
;
336 emit_R10G10B10A2_USCALED( const void *attrib
, void *ptr
)
338 float *src
= (float *)ptr
;
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
);
347 *(uint32_t *)attrib
= value
;
351 emit_R10G10B10A2_SNORM( const void *attrib
, void *ptr
)
353 float *src
= (float *)ptr
;
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
);
362 *(uint32_t *)attrib
= value
;
366 emit_R10G10B10A2_SSCALED( const void *attrib
, void *ptr
)
368 float *src
= (float *)ptr
;
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
);
377 *(uint32_t *)attrib
= value
;
381 emit_NULL( const void *attrib
, void *ptr
)
383 /* do nothing is the only sensible option */
386 static emit_func
get_emit_func( enum pipe_format 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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
524 case PIPE_FORMAT_B8G8R8A8_UNORM
:
525 return &emit_B8G8R8A8_UNORM
;
527 case PIPE_FORMAT_A8R8G8B8_UNORM
:
528 return &emit_A8R8G8B8_UNORM
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
608 static ALWAYS_INLINE
void PIPE_CDECL
generic_run_one( struct translate_generic
*tg
,
610 unsigned instance_id
,
613 unsigned nr_attrs
= tg
->nr_attrib
;
616 for (attr
= 0; attr
< nr_attrs
; attr
++) {
618 uint8_t *dst
= (uint8_t *)vert
+ tg
->attrib
[attr
].output_offset
;
620 if (tg
->attrib
[attr
].type
== TRANSLATE_ELEMENT_NORMAL
) {
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().
634 /* clamp to avoid going out of bounds */
635 index
= MIN2(index
, tg
->attrib
[attr
].max_index
);
638 src
= tg
->attrib
[attr
].input_ptr
+
639 tg
->attrib
[attr
].input_stride
* index
;
641 copy_size
= tg
->attrib
[attr
].copy_size
;
642 if(likely(copy_size
>= 0))
643 memcpy(dst
, src
, copy_size
);
646 tg
->attrib
[attr
].fetch( data
, src
, 0, 0 );
649 debug_printf("Fetch linear attr %d from %p stride %d index %d: "
650 " %f, %f, %f, %f \n",
652 tg
->attrib
[attr
].input_ptr
,
653 tg
->attrib
[attr
].input_stride
,
655 data
[0], data
[1],data
[2], data
[3]);
657 tg
->attrib
[attr
].emit( data
, dst
);
660 if(likely(tg
->attrib
[attr
].copy_size
>= 0))
661 memcpy(data
, &instance_id
, 4);
664 data
[0] = (float)instance_id
;
665 tg
->attrib
[attr
].emit( data
, dst
);
672 * Fetch vertex attributes for 'count' vertices.
674 static void PIPE_CDECL
generic_run_elts( struct translate
*translate
,
675 const unsigned *elts
,
677 unsigned instance_id
,
678 void *output_buffer
)
680 struct translate_generic
*tg
= translate_generic(translate
);
681 char *vert
= output_buffer
;
684 for (i
= 0; i
< count
; i
++) {
685 generic_run_one(tg
, *elts
++, instance_id
, vert
);
686 vert
+= tg
->translate
.key
.output_stride
;
690 static void PIPE_CDECL
generic_run_elts16( struct translate
*translate
,
691 const uint16_t *elts
,
693 unsigned instance_id
,
694 void *output_buffer
)
696 struct translate_generic
*tg
= translate_generic(translate
);
697 char *vert
= output_buffer
;
700 for (i
= 0; i
< count
; i
++) {
701 generic_run_one(tg
, *elts
++, instance_id
, vert
);
702 vert
+= tg
->translate
.key
.output_stride
;
706 static void PIPE_CDECL
generic_run_elts8( struct translate
*translate
,
709 unsigned instance_id
,
710 void *output_buffer
)
712 struct translate_generic
*tg
= translate_generic(translate
);
713 char *vert
= output_buffer
;
716 for (i
= 0; i
< count
; i
++) {
717 generic_run_one(tg
, *elts
++, instance_id
, vert
);
718 vert
+= tg
->translate
.key
.output_stride
;
722 static void PIPE_CDECL
generic_run( struct translate
*translate
,
725 unsigned instance_id
,
726 void *output_buffer
)
728 struct translate_generic
*tg
= translate_generic(translate
);
729 char *vert
= output_buffer
;
732 for (i
= 0; i
< count
; i
++) {
733 generic_run_one(tg
, start
+ i
, instance_id
, vert
);
734 vert
+= tg
->translate
.key
.output_stride
;
740 static void generic_set_buffer( struct translate
*translate
,
746 struct translate_generic
*tg
= translate_generic(translate
);
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
;
760 static void generic_release( struct translate
*translate
)
768 is_legal_int_format_combo( const struct util_format_description
*src
,
769 const struct util_format_description
*dst
)
772 unsigned nr
= MIN2(src
->nr_channels
, dst
->nr_channels
);
774 for (i
= 0; i
< nr
; i
++) {
775 /* The signs must match. */
776 if (src
->channel
[i
].type
!= src
->channel
[i
].type
) {
780 /* Integers must not lose precision at any point in the pipeline. */
781 if (src
->channel
[i
].size
> dst
->channel
[i
].size
) {
788 struct translate
*translate_generic_create( const struct translate_key
*key
)
790 struct translate_generic
*tg
= CALLOC_STRUCT(translate_generic
);
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
;
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
);
809 assert(format_desc
->fetch_rgba_float
);
811 tg
->attrib
[i
].type
= key
->element
[i
].type
;
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
);
817 if (!is_legal_int_format_combo(format_desc
, out_format_desc
)) {
822 if (format_desc
->channel
[0].type
== UTIL_FORMAT_TYPE_SIGNED
) {
823 tg
->attrib
[i
].fetch
= (fetch_func
)format_desc
->fetch_rgba_sint
;
825 tg
->attrib
[i
].fetch
= (fetch_func
)format_desc
->fetch_rgba_uint
;
828 tg
->attrib
[i
].fetch
= (fetch_func
)format_desc
->fetch_rgba_float
;
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
;
835 tg
->attrib
[i
].output_offset
= key
->element
[i
].output_offset
;
837 tg
->attrib
[i
].copy_size
= -1;
838 if (tg
->attrib
[i
].type
== TRANSLATE_ELEMENT_INSTANCE_ID
)
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;
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;
853 if(tg
->attrib
[i
].copy_size
< 0)
854 tg
->attrib
[i
].emit
= get_emit_func(key
->element
[i
].output_format
);
856 tg
->attrib
[i
].emit
= NULL
;
859 tg
->nr_attrib
= key
->nr_elements
;
862 return &tg
->translate
;
865 boolean
translate_generic_is_output_format_supported(enum pipe_format format
)
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
944 case PIPE_FORMAT_A8R8G8B8_UNORM
: return TRUE
;
945 case PIPE_FORMAT_B8G8R8A8_UNORM
: return TRUE
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
987 default: return FALSE
;