1 /**************************************************************************
3 * Copyright 2007 VMware, Inc.
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 VMWARE 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 <keithw@vmware.com>
33 #include "util/u_memory.h"
34 #include "util/format/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
69 * output_format != input_format: in this case, u_format is used
70 * to do a full conversion
72 * this value is set to the format size in bytes if
73 * output_format == input_format or for 32-bit instance ids:
74 * in this case, memcpy is used to copy this amount of bytes
78 } attrib
[TRANSLATE_MAX_ATTRIBS
];
84 static struct translate_generic
*
85 translate_generic(struct translate
*translate
)
87 return (struct translate_generic
*)translate
;
92 * Fetch a dword[4] vertex attribute from memory, doing format/type
93 * conversion as needed.
95 * This is probably needed/dupliocated elsewhere, eg format
96 * conversion, texture sampling etc.
98 #define ATTRIB(NAME, SZ, SRCTYPE, DSTTYPE, TO) \
100 emit_##NAME(const void *attrib, void *ptr) \
103 SRCTYPE *in = (SRCTYPE *)attrib; \
104 DSTTYPE *out = (DSTTYPE *)ptr; \
106 for (i = 0; i < SZ; i++) { \
107 out[i] = TO(in[i]); \
112 #define TO_64_FLOAT(x) ((double) x)
113 #define TO_32_FLOAT(x) (x)
114 #define TO_16_FLOAT(x) util_float_to_half(x)
116 #define TO_8_USCALED(x) ((unsigned char) x)
117 #define TO_16_USCALED(x) ((unsigned short) x)
118 #define TO_32_USCALED(x) ((unsigned int) x)
120 #define TO_8_SSCALED(x) ((char) x)
121 #define TO_16_SSCALED(x) ((short) x)
122 #define TO_32_SSCALED(x) ((int) x)
124 #define TO_8_UNORM(x) ((unsigned char) (x * 255.0f))
125 #define TO_16_UNORM(x) ((unsigned short) (x * 65535.0f))
126 #define TO_32_UNORM(x) ((unsigned int) (x * 4294967295.0f))
128 #define TO_8_SNORM(x) ((char) (x * 127.0f))
129 #define TO_16_SNORM(x) ((short) (x * 32767.0f))
130 #define TO_32_SNORM(x) ((int) (x * 2147483647.0f))
132 #define TO_32_FIXED(x) ((int) (x * 65536.0f))
134 #define TO_INT(x) (x)
137 ATTRIB(R64G64B64A64_FLOAT
, 4, float, double, TO_64_FLOAT
)
138 ATTRIB(R64G64B64_FLOAT
, 3, float, double, TO_64_FLOAT
)
139 ATTRIB(R64G64_FLOAT
, 2, float, double, TO_64_FLOAT
)
140 ATTRIB(R64_FLOAT
, 1, float, double, TO_64_FLOAT
)
142 ATTRIB(R32G32B32A32_FLOAT
, 4, float, float, TO_32_FLOAT
)
143 ATTRIB(R32G32B32_FLOAT
, 3, float, float, TO_32_FLOAT
)
144 ATTRIB(R32G32_FLOAT
, 2, float, float, TO_32_FLOAT
)
145 ATTRIB(R32_FLOAT
, 1, float, float, TO_32_FLOAT
)
147 ATTRIB(R16G16B16A16_FLOAT
, 4, float, ushort
, TO_16_FLOAT
)
148 ATTRIB(R16G16B16_FLOAT
, 3, float, ushort
, TO_16_FLOAT
)
149 ATTRIB(R16G16_FLOAT
, 2, float, ushort
, TO_16_FLOAT
)
150 ATTRIB(R16_FLOAT
, 1, float, ushort
, TO_16_FLOAT
)
152 ATTRIB(R32G32B32A32_USCALED
, 4, float, unsigned, TO_32_USCALED
)
153 ATTRIB(R32G32B32_USCALED
, 3, float, unsigned, TO_32_USCALED
)
154 ATTRIB(R32G32_USCALED
, 2, float, unsigned, TO_32_USCALED
)
155 ATTRIB(R32_USCALED
, 1, float, unsigned, TO_32_USCALED
)
157 ATTRIB(R32G32B32A32_SSCALED
, 4, float, int, TO_32_SSCALED
)
158 ATTRIB(R32G32B32_SSCALED
, 3, float, int, TO_32_SSCALED
)
159 ATTRIB(R32G32_SSCALED
, 2, float, int, TO_32_SSCALED
)
160 ATTRIB(R32_SSCALED
, 1, float, int, TO_32_SSCALED
)
162 ATTRIB(R32G32B32A32_UNORM
, 4, float, unsigned, TO_32_UNORM
)
163 ATTRIB(R32G32B32_UNORM
, 3, float, unsigned, TO_32_UNORM
)
164 ATTRIB(R32G32_UNORM
, 2, float, unsigned, TO_32_UNORM
)
165 ATTRIB(R32_UNORM
, 1, float, unsigned, TO_32_UNORM
)
167 ATTRIB(R32G32B32A32_SNORM
, 4, float, int, TO_32_SNORM
)
168 ATTRIB(R32G32B32_SNORM
, 3, float, int, TO_32_SNORM
)
169 ATTRIB(R32G32_SNORM
, 2, float, int, TO_32_SNORM
)
170 ATTRIB(R32_SNORM
, 1, float, int, TO_32_SNORM
)
172 ATTRIB(R16G16B16A16_USCALED
, 4, float, ushort
, TO_16_USCALED
)
173 ATTRIB(R16G16B16_USCALED
, 3, float, ushort
, TO_16_USCALED
)
174 ATTRIB(R16G16_USCALED
, 2, float, ushort
, TO_16_USCALED
)
175 ATTRIB(R16_USCALED
, 1, float, ushort
, TO_16_USCALED
)
177 ATTRIB(R16G16B16A16_SSCALED
, 4, float, short, TO_16_SSCALED
)
178 ATTRIB(R16G16B16_SSCALED
, 3, float, short, TO_16_SSCALED
)
179 ATTRIB(R16G16_SSCALED
, 2, float, short, TO_16_SSCALED
)
180 ATTRIB(R16_SSCALED
, 1, float, short, TO_16_SSCALED
)
182 ATTRIB(R16G16B16A16_UNORM
, 4, float, ushort
, TO_16_UNORM
)
183 ATTRIB(R16G16B16_UNORM
, 3, float, ushort
, TO_16_UNORM
)
184 ATTRIB(R16G16_UNORM
, 2, float, ushort
, TO_16_UNORM
)
185 ATTRIB(R16_UNORM
, 1, float, ushort
, TO_16_UNORM
)
187 ATTRIB(R16G16B16A16_SNORM
, 4, float, short, TO_16_SNORM
)
188 ATTRIB(R16G16B16_SNORM
, 3, float, short, TO_16_SNORM
)
189 ATTRIB(R16G16_SNORM
, 2, float, short, TO_16_SNORM
)
190 ATTRIB(R16_SNORM
, 1, float, short, TO_16_SNORM
)
192 ATTRIB(R8G8B8A8_USCALED
, 4, float, ubyte
, TO_8_USCALED
)
193 ATTRIB(R8G8B8_USCALED
, 3, float, ubyte
, TO_8_USCALED
)
194 ATTRIB(R8G8_USCALED
, 2, float, ubyte
, TO_8_USCALED
)
195 ATTRIB(R8_USCALED
, 1, float, ubyte
, TO_8_USCALED
)
197 ATTRIB(R8G8B8A8_SSCALED
, 4, float, char, TO_8_SSCALED
)
198 ATTRIB(R8G8B8_SSCALED
, 3, float, char, TO_8_SSCALED
)
199 ATTRIB(R8G8_SSCALED
, 2, float, char, TO_8_SSCALED
)
200 ATTRIB(R8_SSCALED
, 1, float, char, TO_8_SSCALED
)
202 ATTRIB(R8G8B8A8_UNORM
, 4, float, ubyte
, TO_8_UNORM
)
203 ATTRIB(R8G8B8_UNORM
, 3, float, ubyte
, TO_8_UNORM
)
204 ATTRIB(R8G8_UNORM
, 2, float, ubyte
, TO_8_UNORM
)
205 ATTRIB(R8_UNORM
, 1, float, ubyte
, TO_8_UNORM
)
207 ATTRIB(R8G8B8A8_SNORM
, 4, float, char, TO_8_SNORM
)
208 ATTRIB(R8G8B8_SNORM
, 3, float, char, TO_8_SNORM
)
209 ATTRIB(R8G8_SNORM
, 2, float, char, TO_8_SNORM
)
210 ATTRIB(R8_SNORM
, 1, float, char, TO_8_SNORM
)
212 ATTRIB(R32G32B32A32_UINT
, 4, uint32_t, unsigned, TO_INT
)
213 ATTRIB(R32G32B32_UINT
, 3, uint32_t, unsigned, TO_INT
)
214 ATTRIB(R32G32_UINT
, 2, uint32_t, unsigned, TO_INT
)
215 ATTRIB(R32_UINT
, 1, uint32_t, unsigned, TO_INT
)
217 ATTRIB(R16G16B16A16_UINT
, 4, uint32_t, ushort
, TO_INT
)
218 ATTRIB(R16G16B16_UINT
, 3, uint32_t, ushort
, TO_INT
)
219 ATTRIB(R16G16_UINT
, 2, uint32_t, ushort
, TO_INT
)
220 ATTRIB(R16_UINT
, 1, uint32_t, ushort
, TO_INT
)
222 ATTRIB(R8G8B8A8_UINT
, 4, uint32_t, ubyte
, TO_INT
)
223 ATTRIB(R8G8B8_UINT
, 3, uint32_t, ubyte
, TO_INT
)
224 ATTRIB(R8G8_UINT
, 2, uint32_t, ubyte
, TO_INT
)
225 ATTRIB(R8_UINT
, 1, uint32_t, ubyte
, TO_INT
)
227 ATTRIB(R32G32B32A32_SINT
, 4, int32_t, int, TO_INT
)
228 ATTRIB(R32G32B32_SINT
, 3, int32_t, int, TO_INT
)
229 ATTRIB(R32G32_SINT
, 2, int32_t, int, TO_INT
)
230 ATTRIB(R32_SINT
, 1, int32_t, int, TO_INT
)
232 ATTRIB(R16G16B16A16_SINT
, 4, int32_t, short, TO_INT
)
233 ATTRIB(R16G16B16_SINT
, 3, int32_t, short, TO_INT
)
234 ATTRIB(R16G16_SINT
, 2, int32_t, short, TO_INT
)
235 ATTRIB(R16_SINT
, 1, int32_t, short, TO_INT
)
237 ATTRIB(R8G8B8A8_SINT
, 4, int32_t, char, TO_INT
)
238 ATTRIB(R8G8B8_SINT
, 3, int32_t, char, TO_INT
)
239 ATTRIB(R8G8_SINT
, 2, int32_t, char, TO_INT
)
240 ATTRIB(R8_SINT
, 1, int32_t, char, TO_INT
)
243 emit_A8R8G8B8_UNORM(const void *attrib
, void *ptr
)
245 float *in
= (float *)attrib
;
246 ubyte
*out
= (ubyte
*)ptr
;
247 out
[0] = TO_8_UNORM(in
[3]);
248 out
[1] = TO_8_UNORM(in
[0]);
249 out
[2] = TO_8_UNORM(in
[1]);
250 out
[3] = TO_8_UNORM(in
[2]);
254 emit_B8G8R8A8_UNORM(const void *attrib
, void *ptr
)
256 float *in
= (float *)attrib
;
257 ubyte
*out
= (ubyte
*)ptr
;
258 out
[2] = TO_8_UNORM(in
[0]);
259 out
[1] = TO_8_UNORM(in
[1]);
260 out
[0] = TO_8_UNORM(in
[2]);
261 out
[3] = TO_8_UNORM(in
[3]);
265 emit_B10G10R10A2_UNORM(const void *attrib
, void *ptr
)
267 float *src
= (float *)ptr
;
269 value
|= ((uint32_t)(CLAMP(src
[2], 0, 1) * 0x3ff)) & 0x3ff;
270 value
|= (((uint32_t)(CLAMP(src
[1], 0, 1) * 0x3ff)) & 0x3ff) << 10;
271 value
|= (((uint32_t)(CLAMP(src
[0], 0, 1) * 0x3ff)) & 0x3ff) << 20;
272 value
|= ((uint32_t)(CLAMP(src
[3], 0, 1) * 0x3)) << 30;
273 *(uint32_t *)attrib
= util_le32_to_cpu(value
);
277 emit_B10G10R10A2_USCALED(const void *attrib
, void *ptr
)
279 float *src
= (float *)ptr
;
281 value
|= ((uint32_t)CLAMP(src
[2], 0, 1023)) & 0x3ff;
282 value
|= (((uint32_t)CLAMP(src
[1], 0, 1023)) & 0x3ff) << 10;
283 value
|= (((uint32_t)CLAMP(src
[0], 0, 1023)) & 0x3ff) << 20;
284 value
|= ((uint32_t)CLAMP(src
[3], 0, 3)) << 30;
285 *(uint32_t *)attrib
= util_le32_to_cpu(value
);
289 emit_B10G10R10A2_SNORM(const void *attrib
, void *ptr
)
291 float *src
= (float *)ptr
;
293 value
|= (uint32_t)(((uint32_t)(CLAMP(src
[2], -1, 1) * 0x1ff)) & 0x3ff) ;
294 value
|= (uint32_t)((((uint32_t)(CLAMP(src
[1], -1, 1) * 0x1ff)) & 0x3ff) << 10) ;
295 value
|= (uint32_t)((((uint32_t)(CLAMP(src
[0], -1, 1) * 0x1ff)) & 0x3ff) << 20) ;
296 value
|= (uint32_t)(((uint32_t)(CLAMP(src
[3], -1, 1) * 0x1)) << 30) ;
297 *(uint32_t *)attrib
= util_le32_to_cpu(value
);
301 emit_B10G10R10A2_SSCALED(const void *attrib
, void *ptr
)
303 float *src
= (float *)ptr
;
305 value
|= (uint32_t)(((uint32_t)CLAMP(src
[2], -512, 511)) & 0x3ff) ;
306 value
|= (uint32_t)((((uint32_t)CLAMP(src
[1], -512, 511)) & 0x3ff) << 10) ;
307 value
|= (uint32_t)((((uint32_t)CLAMP(src
[0], -512, 511)) & 0x3ff) << 20) ;
308 value
|= (uint32_t)(((uint32_t)CLAMP(src
[3], -2, 1)) << 30) ;
309 *(uint32_t *)attrib
= util_le32_to_cpu(value
);
313 emit_R10G10B10A2_UNORM(const void *attrib
, void *ptr
)
315 float *src
= (float *)ptr
;
317 value
|= ((uint32_t)(CLAMP(src
[0], 0, 1) * 0x3ff)) & 0x3ff;
318 value
|= (((uint32_t)(CLAMP(src
[1], 0, 1) * 0x3ff)) & 0x3ff) << 10;
319 value
|= (((uint32_t)(CLAMP(src
[2], 0, 1) * 0x3ff)) & 0x3ff) << 20;
320 value
|= ((uint32_t)(CLAMP(src
[3], 0, 1) * 0x3)) << 30;
321 *(uint32_t *)attrib
= util_le32_to_cpu(value
);
325 emit_R10G10B10A2_USCALED(const void *attrib
, void *ptr
)
327 float *src
= (float *)ptr
;
329 value
|= ((uint32_t)CLAMP(src
[0], 0, 1023)) & 0x3ff;
330 value
|= (((uint32_t)CLAMP(src
[1], 0, 1023)) & 0x3ff) << 10;
331 value
|= (((uint32_t)CLAMP(src
[2], 0, 1023)) & 0x3ff) << 20;
332 value
|= ((uint32_t)CLAMP(src
[3], 0, 3)) << 30;
333 *(uint32_t *)attrib
= util_le32_to_cpu(value
);
337 emit_R10G10B10A2_SNORM(const void *attrib
, void *ptr
)
339 float *src
= (float *)ptr
;
341 value
|= (uint32_t)(((uint32_t)(CLAMP(src
[0], -1, 1) * 0x1ff)) & 0x3ff) ;
342 value
|= (uint32_t)((((uint32_t)(CLAMP(src
[1], -1, 1) * 0x1ff)) & 0x3ff) << 10) ;
343 value
|= (uint32_t)((((uint32_t)(CLAMP(src
[2], -1, 1) * 0x1ff)) & 0x3ff) << 20) ;
344 value
|= (uint32_t)(((uint32_t)(CLAMP(src
[3], -1, 1) * 0x1)) << 30) ;
345 *(uint32_t *)attrib
= util_le32_to_cpu(value
);
349 emit_R10G10B10A2_SSCALED(const void *attrib
, void *ptr
)
351 float *src
= (float *)ptr
;
353 value
|= (uint32_t)(((uint32_t)CLAMP(src
[0], -512, 511)) & 0x3ff) ;
354 value
|= (uint32_t)((((uint32_t)CLAMP(src
[1], -512, 511)) & 0x3ff) << 10) ;
355 value
|= (uint32_t)((((uint32_t)CLAMP(src
[2], -512, 511)) & 0x3ff) << 20) ;
356 value
|= (uint32_t)(((uint32_t)CLAMP(src
[3], -2, 1)) << 30) ;
357 *(uint32_t *)attrib
= util_le32_to_cpu(value
);
361 emit_NULL(const void *attrib
, void *ptr
)
363 /* do nothing is the only sensible option */
367 get_emit_func(enum pipe_format format
)
370 case PIPE_FORMAT_R64_FLOAT
:
371 return &emit_R64_FLOAT
;
372 case PIPE_FORMAT_R64G64_FLOAT
:
373 return &emit_R64G64_FLOAT
;
374 case PIPE_FORMAT_R64G64B64_FLOAT
:
375 return &emit_R64G64B64_FLOAT
;
376 case PIPE_FORMAT_R64G64B64A64_FLOAT
:
377 return &emit_R64G64B64A64_FLOAT
;
379 case PIPE_FORMAT_R32_FLOAT
:
380 return &emit_R32_FLOAT
;
381 case PIPE_FORMAT_R32G32_FLOAT
:
382 return &emit_R32G32_FLOAT
;
383 case PIPE_FORMAT_R32G32B32_FLOAT
:
384 return &emit_R32G32B32_FLOAT
;
385 case PIPE_FORMAT_R32G32B32A32_FLOAT
:
386 return &emit_R32G32B32A32_FLOAT
;
388 case PIPE_FORMAT_R16_FLOAT
:
389 return &emit_R16_FLOAT
;
390 case PIPE_FORMAT_R16G16_FLOAT
:
391 return &emit_R16G16_FLOAT
;
392 case PIPE_FORMAT_R16G16B16_FLOAT
:
393 return &emit_R16G16B16_FLOAT
;
394 case PIPE_FORMAT_R16G16B16A16_FLOAT
:
395 return &emit_R16G16B16A16_FLOAT
;
397 case PIPE_FORMAT_R32_UNORM
:
398 return &emit_R32_UNORM
;
399 case PIPE_FORMAT_R32G32_UNORM
:
400 return &emit_R32G32_UNORM
;
401 case PIPE_FORMAT_R32G32B32_UNORM
:
402 return &emit_R32G32B32_UNORM
;
403 case PIPE_FORMAT_R32G32B32A32_UNORM
:
404 return &emit_R32G32B32A32_UNORM
;
406 case PIPE_FORMAT_R32_USCALED
:
407 return &emit_R32_USCALED
;
408 case PIPE_FORMAT_R32G32_USCALED
:
409 return &emit_R32G32_USCALED
;
410 case PIPE_FORMAT_R32G32B32_USCALED
:
411 return &emit_R32G32B32_USCALED
;
412 case PIPE_FORMAT_R32G32B32A32_USCALED
:
413 return &emit_R32G32B32A32_USCALED
;
415 case PIPE_FORMAT_R32_SNORM
:
416 return &emit_R32_SNORM
;
417 case PIPE_FORMAT_R32G32_SNORM
:
418 return &emit_R32G32_SNORM
;
419 case PIPE_FORMAT_R32G32B32_SNORM
:
420 return &emit_R32G32B32_SNORM
;
421 case PIPE_FORMAT_R32G32B32A32_SNORM
:
422 return &emit_R32G32B32A32_SNORM
;
424 case PIPE_FORMAT_R32_SSCALED
:
425 return &emit_R32_SSCALED
;
426 case PIPE_FORMAT_R32G32_SSCALED
:
427 return &emit_R32G32_SSCALED
;
428 case PIPE_FORMAT_R32G32B32_SSCALED
:
429 return &emit_R32G32B32_SSCALED
;
430 case PIPE_FORMAT_R32G32B32A32_SSCALED
:
431 return &emit_R32G32B32A32_SSCALED
;
433 case PIPE_FORMAT_R16_UNORM
:
434 return &emit_R16_UNORM
;
435 case PIPE_FORMAT_R16G16_UNORM
:
436 return &emit_R16G16_UNORM
;
437 case PIPE_FORMAT_R16G16B16_UNORM
:
438 return &emit_R16G16B16_UNORM
;
439 case PIPE_FORMAT_R16G16B16A16_UNORM
:
440 return &emit_R16G16B16A16_UNORM
;
442 case PIPE_FORMAT_R16_USCALED
:
443 return &emit_R16_USCALED
;
444 case PIPE_FORMAT_R16G16_USCALED
:
445 return &emit_R16G16_USCALED
;
446 case PIPE_FORMAT_R16G16B16_USCALED
:
447 return &emit_R16G16B16_USCALED
;
448 case PIPE_FORMAT_R16G16B16A16_USCALED
:
449 return &emit_R16G16B16A16_USCALED
;
451 case PIPE_FORMAT_R16_SNORM
:
452 return &emit_R16_SNORM
;
453 case PIPE_FORMAT_R16G16_SNORM
:
454 return &emit_R16G16_SNORM
;
455 case PIPE_FORMAT_R16G16B16_SNORM
:
456 return &emit_R16G16B16_SNORM
;
457 case PIPE_FORMAT_R16G16B16A16_SNORM
:
458 return &emit_R16G16B16A16_SNORM
;
460 case PIPE_FORMAT_R16_SSCALED
:
461 return &emit_R16_SSCALED
;
462 case PIPE_FORMAT_R16G16_SSCALED
:
463 return &emit_R16G16_SSCALED
;
464 case PIPE_FORMAT_R16G16B16_SSCALED
:
465 return &emit_R16G16B16_SSCALED
;
466 case PIPE_FORMAT_R16G16B16A16_SSCALED
:
467 return &emit_R16G16B16A16_SSCALED
;
469 case PIPE_FORMAT_R8_UNORM
:
470 return &emit_R8_UNORM
;
471 case PIPE_FORMAT_R8G8_UNORM
:
472 return &emit_R8G8_UNORM
;
473 case PIPE_FORMAT_R8G8B8_UNORM
:
474 return &emit_R8G8B8_UNORM
;
475 case PIPE_FORMAT_R8G8B8A8_UNORM
:
476 return &emit_R8G8B8A8_UNORM
;
478 case PIPE_FORMAT_R8_USCALED
:
479 return &emit_R8_USCALED
;
480 case PIPE_FORMAT_R8G8_USCALED
:
481 return &emit_R8G8_USCALED
;
482 case PIPE_FORMAT_R8G8B8_USCALED
:
483 return &emit_R8G8B8_USCALED
;
484 case PIPE_FORMAT_R8G8B8A8_USCALED
:
485 return &emit_R8G8B8A8_USCALED
;
487 case PIPE_FORMAT_R8_SNORM
:
488 return &emit_R8_SNORM
;
489 case PIPE_FORMAT_R8G8_SNORM
:
490 return &emit_R8G8_SNORM
;
491 case PIPE_FORMAT_R8G8B8_SNORM
:
492 return &emit_R8G8B8_SNORM
;
493 case PIPE_FORMAT_R8G8B8A8_SNORM
:
494 return &emit_R8G8B8A8_SNORM
;
496 case PIPE_FORMAT_R8_SSCALED
:
497 return &emit_R8_SSCALED
;
498 case PIPE_FORMAT_R8G8_SSCALED
:
499 return &emit_R8G8_SSCALED
;
500 case PIPE_FORMAT_R8G8B8_SSCALED
:
501 return &emit_R8G8B8_SSCALED
;
502 case PIPE_FORMAT_R8G8B8A8_SSCALED
:
503 return &emit_R8G8B8A8_SSCALED
;
505 case PIPE_FORMAT_B8G8R8A8_UNORM
:
506 return &emit_B8G8R8A8_UNORM
;
508 case PIPE_FORMAT_A8R8G8B8_UNORM
:
509 return &emit_A8R8G8B8_UNORM
;
511 case PIPE_FORMAT_R32_UINT
:
512 return &emit_R32_UINT
;
513 case PIPE_FORMAT_R32G32_UINT
:
514 return &emit_R32G32_UINT
;
515 case PIPE_FORMAT_R32G32B32_UINT
:
516 return &emit_R32G32B32_UINT
;
517 case PIPE_FORMAT_R32G32B32A32_UINT
:
518 return &emit_R32G32B32A32_UINT
;
520 case PIPE_FORMAT_R16_UINT
:
521 return &emit_R16_UINT
;
522 case PIPE_FORMAT_R16G16_UINT
:
523 return &emit_R16G16_UINT
;
524 case PIPE_FORMAT_R16G16B16_UINT
:
525 return &emit_R16G16B16_UINT
;
526 case PIPE_FORMAT_R16G16B16A16_UINT
:
527 return &emit_R16G16B16A16_UINT
;
529 case PIPE_FORMAT_R8_UINT
:
530 return &emit_R8_UINT
;
531 case PIPE_FORMAT_R8G8_UINT
:
532 return &emit_R8G8_UINT
;
533 case PIPE_FORMAT_R8G8B8_UINT
:
534 return &emit_R8G8B8_UINT
;
535 case PIPE_FORMAT_R8G8B8A8_UINT
:
536 return &emit_R8G8B8A8_UINT
;
538 case PIPE_FORMAT_R32_SINT
:
539 return &emit_R32_SINT
;
540 case PIPE_FORMAT_R32G32_SINT
:
541 return &emit_R32G32_SINT
;
542 case PIPE_FORMAT_R32G32B32_SINT
:
543 return &emit_R32G32B32_SINT
;
544 case PIPE_FORMAT_R32G32B32A32_SINT
:
545 return &emit_R32G32B32A32_SINT
;
547 case PIPE_FORMAT_R16_SINT
:
548 return &emit_R16_SINT
;
549 case PIPE_FORMAT_R16G16_SINT
:
550 return &emit_R16G16_SINT
;
551 case PIPE_FORMAT_R16G16B16_SINT
:
552 return &emit_R16G16B16_SINT
;
553 case PIPE_FORMAT_R16G16B16A16_SINT
:
554 return &emit_R16G16B16A16_SINT
;
556 case PIPE_FORMAT_R8_SINT
:
557 return &emit_R8_SINT
;
558 case PIPE_FORMAT_R8G8_SINT
:
559 return &emit_R8G8_SINT
;
560 case PIPE_FORMAT_R8G8B8_SINT
:
561 return &emit_R8G8B8_SINT
;
562 case PIPE_FORMAT_R8G8B8A8_SINT
:
563 return &emit_R8G8B8A8_SINT
;
565 case PIPE_FORMAT_B10G10R10A2_UNORM
:
566 return &emit_B10G10R10A2_UNORM
;
567 case PIPE_FORMAT_B10G10R10A2_USCALED
:
568 return &emit_B10G10R10A2_USCALED
;
569 case PIPE_FORMAT_B10G10R10A2_SNORM
:
570 return &emit_B10G10R10A2_SNORM
;
571 case PIPE_FORMAT_B10G10R10A2_SSCALED
:
572 return &emit_B10G10R10A2_SSCALED
;
574 case PIPE_FORMAT_R10G10B10A2_UNORM
:
575 return &emit_R10G10B10A2_UNORM
;
576 case PIPE_FORMAT_R10G10B10A2_USCALED
:
577 return &emit_R10G10B10A2_USCALED
;
578 case PIPE_FORMAT_R10G10B10A2_SNORM
:
579 return &emit_R10G10B10A2_SNORM
;
580 case PIPE_FORMAT_R10G10B10A2_SSCALED
:
581 return &emit_R10G10B10A2_SSCALED
;
589 static ALWAYS_INLINE
void PIPE_CDECL
590 generic_run_one(struct translate_generic
*tg
,
592 unsigned start_instance
,
593 unsigned instance_id
,
596 unsigned nr_attrs
= tg
->nr_attrib
;
599 for (attr
= 0; attr
< nr_attrs
; attr
++) {
601 uint8_t *dst
= (uint8_t *)vert
+ tg
->attrib
[attr
].output_offset
;
603 if (tg
->attrib
[attr
].type
== TRANSLATE_ELEMENT_NORMAL
) {
608 if (tg
->attrib
[attr
].instance_divisor
) {
609 index
= start_instance
;
610 index
+= (instance_id
/ tg
->attrib
[attr
].instance_divisor
);
611 /* XXX we need to clamp the index here too, but to a
612 * per-array max value, not the draw->pt.max_index value
613 * that's being given to us via translate->set_buffer().
618 /* clamp to avoid going out of bounds */
619 index
= MIN2(index
, tg
->attrib
[attr
].max_index
);
622 src
= tg
->attrib
[attr
].input_ptr
+
623 (ptrdiff_t)tg
->attrib
[attr
].input_stride
* index
;
625 copy_size
= tg
->attrib
[attr
].copy_size
;
626 if (likely(copy_size
>= 0)) {
627 memcpy(dst
, src
, copy_size
);
629 tg
->attrib
[attr
].fetch(data
, src
, 0, 0);
632 debug_printf("Fetch linear attr %d from %p stride %d index %d: "
633 " %f, %f, %f, %f \n",
635 tg
->attrib
[attr
].input_ptr
,
636 tg
->attrib
[attr
].input_stride
,
638 data
[0], data
[1],data
[2], data
[3]);
640 tg
->attrib
[attr
].emit(data
, dst
);
643 if (likely(tg
->attrib
[attr
].copy_size
>= 0)) {
644 memcpy(data
, &instance_id
, 4);
646 data
[0] = (float)instance_id
;
647 tg
->attrib
[attr
].emit(data
, dst
);
654 * Fetch vertex attributes for 'count' vertices.
656 static void PIPE_CDECL
657 generic_run_elts(struct translate
*translate
,
658 const unsigned *elts
,
660 unsigned start_instance
,
661 unsigned instance_id
,
664 struct translate_generic
*tg
= translate_generic(translate
);
665 char *vert
= output_buffer
;
668 for (i
= 0; i
< count
; i
++) {
669 generic_run_one(tg
, *elts
++, start_instance
, instance_id
, vert
);
670 vert
+= tg
->translate
.key
.output_stride
;
674 static void PIPE_CDECL
675 generic_run_elts16(struct translate
*translate
,
676 const uint16_t *elts
,
678 unsigned start_instance
,
679 unsigned instance_id
,
682 struct translate_generic
*tg
= translate_generic(translate
);
683 char *vert
= output_buffer
;
686 for (i
= 0; i
< count
; i
++) {
687 generic_run_one(tg
, *elts
++, start_instance
, instance_id
, vert
);
688 vert
+= tg
->translate
.key
.output_stride
;
692 static void PIPE_CDECL
693 generic_run_elts8(struct translate
*translate
,
696 unsigned start_instance
,
697 unsigned instance_id
,
700 struct translate_generic
*tg
= translate_generic(translate
);
701 char *vert
= output_buffer
;
704 for (i
= 0; i
< count
; i
++) {
705 generic_run_one(tg
, *elts
++, start_instance
, instance_id
, vert
);
706 vert
+= tg
->translate
.key
.output_stride
;
710 static void PIPE_CDECL
711 generic_run(struct translate
*translate
,
714 unsigned start_instance
,
715 unsigned instance_id
,
718 struct translate_generic
*tg
= translate_generic(translate
);
719 char *vert
= output_buffer
;
722 for (i
= 0; i
< count
; i
++) {
723 generic_run_one(tg
, start
+ i
, start_instance
, instance_id
, vert
);
724 vert
+= tg
->translate
.key
.output_stride
;
731 generic_set_buffer(struct translate
*translate
,
737 struct translate_generic
*tg
= translate_generic(translate
);
740 for (i
= 0; i
< tg
->nr_attrib
; i
++) {
741 if (tg
->attrib
[i
].buffer
== buf
) {
742 tg
->attrib
[i
].input_ptr
= ((const uint8_t *)ptr
+
743 tg
->attrib
[i
].input_offset
);
744 tg
->attrib
[i
].input_stride
= stride
;
745 tg
->attrib
[i
].max_index
= max_index
;
752 generic_release(struct translate
*translate
)
760 is_legal_int_format_combo(const struct util_format_description
*src
,
761 const struct util_format_description
*dst
)
764 unsigned nr
= MIN2(src
->nr_channels
, dst
->nr_channels
);
766 for (i
= 0; i
< nr
; i
++) {
767 /* The signs must match. */
768 if (src
->channel
[i
].type
!= dst
->channel
[i
].type
) {
772 /* Integers must not lose precision at any point in the pipeline. */
773 if (src
->channel
[i
].size
> dst
->channel
[i
].size
) {
781 translate_generic_create(const struct translate_key
*key
)
783 struct translate_generic
*tg
= CALLOC_STRUCT(translate_generic
);
789 assert(key
->nr_elements
<= TRANSLATE_MAX_ATTRIBS
);
791 tg
->translate
.key
= *key
;
792 tg
->translate
.release
= generic_release
;
793 tg
->translate
.set_buffer
= generic_set_buffer
;
794 tg
->translate
.run_elts
= generic_run_elts
;
795 tg
->translate
.run_elts16
= generic_run_elts16
;
796 tg
->translate
.run_elts8
= generic_run_elts8
;
797 tg
->translate
.run
= generic_run
;
799 for (i
= 0; i
< key
->nr_elements
; i
++) {
800 const struct util_format_description
*format_desc
=
801 util_format_description(key
->element
[i
].input_format
);
802 const struct util_format_unpack_description
*unpack
=
803 util_format_unpack_description(key
->element
[i
].input_format
);
807 tg
->attrib
[i
].type
= key
->element
[i
].type
;
809 if (format_desc
->channel
[0].pure_integer
) {
810 const struct util_format_description
*out_format_desc
=
811 util_format_description(key
->element
[i
].output_format
);
813 if (!is_legal_int_format_combo(format_desc
, out_format_desc
)) {
818 if (format_desc
->channel
[0].type
== UTIL_FORMAT_TYPE_SIGNED
) {
819 assert(unpack
->fetch_rgba_sint
);
820 tg
->attrib
[i
].fetch
= (fetch_func
)unpack
->fetch_rgba_sint
;
822 assert(unpack
->fetch_rgba_uint
);
823 tg
->attrib
[i
].fetch
= (fetch_func
)unpack
->fetch_rgba_uint
;
826 assert(unpack
->fetch_rgba_float
);
827 tg
->attrib
[i
].fetch
= (fetch_func
)unpack
->fetch_rgba_float
;
830 tg
->attrib
[i
].buffer
= key
->element
[i
].input_buffer
;
831 tg
->attrib
[i
].input_offset
= key
->element
[i
].input_offset
;
832 tg
->attrib
[i
].instance_divisor
= key
->element
[i
].instance_divisor
;
834 tg
->attrib
[i
].output_offset
= key
->element
[i
].output_offset
;
836 tg
->attrib
[i
].copy_size
= -1;
837 if (tg
->attrib
[i
].type
== TRANSLATE_ELEMENT_INSTANCE_ID
) {
838 if (key
->element
[i
].output_format
== PIPE_FORMAT_R32_USCALED
839 || key
->element
[i
].output_format
== PIPE_FORMAT_R32_SSCALED
)
840 tg
->attrib
[i
].copy_size
= 4;
842 if (key
->element
[i
].input_format
== key
->element
[i
].output_format
843 && format_desc
->block
.width
== 1
844 && format_desc
->block
.height
== 1
845 && !(format_desc
->block
.bits
& 7))
846 tg
->attrib
[i
].copy_size
= format_desc
->block
.bits
>> 3;
849 if (tg
->attrib
[i
].copy_size
< 0)
850 tg
->attrib
[i
].emit
= get_emit_func(key
->element
[i
].output_format
);
852 tg
->attrib
[i
].emit
= NULL
;
855 tg
->nr_attrib
= key
->nr_elements
;
857 return &tg
->translate
;
861 translate_generic_is_output_format_supported(enum pipe_format format
)
864 case PIPE_FORMAT_R64G64B64A64_FLOAT
: return TRUE
;
865 case PIPE_FORMAT_R64G64B64_FLOAT
: return TRUE
;
866 case PIPE_FORMAT_R64G64_FLOAT
: return TRUE
;
867 case PIPE_FORMAT_R64_FLOAT
: return TRUE
;
869 case PIPE_FORMAT_R32G32B32A32_FLOAT
: return TRUE
;
870 case PIPE_FORMAT_R32G32B32_FLOAT
: return TRUE
;
871 case PIPE_FORMAT_R32G32_FLOAT
: return TRUE
;
872 case PIPE_FORMAT_R32_FLOAT
: return TRUE
;
874 case PIPE_FORMAT_R16G16B16A16_FLOAT
: return TRUE
;
875 case PIPE_FORMAT_R16G16B16_FLOAT
: return TRUE
;
876 case PIPE_FORMAT_R16G16_FLOAT
: return TRUE
;
877 case PIPE_FORMAT_R16_FLOAT
: return TRUE
;
879 case PIPE_FORMAT_R32G32B32A32_USCALED
: return TRUE
;
880 case PIPE_FORMAT_R32G32B32_USCALED
: return TRUE
;
881 case PIPE_FORMAT_R32G32_USCALED
: return TRUE
;
882 case PIPE_FORMAT_R32_USCALED
: return TRUE
;
884 case PIPE_FORMAT_R32G32B32A32_SSCALED
: return TRUE
;
885 case PIPE_FORMAT_R32G32B32_SSCALED
: return TRUE
;
886 case PIPE_FORMAT_R32G32_SSCALED
: return TRUE
;
887 case PIPE_FORMAT_R32_SSCALED
: return TRUE
;
889 case PIPE_FORMAT_R32G32B32A32_UNORM
: return TRUE
;
890 case PIPE_FORMAT_R32G32B32_UNORM
: return TRUE
;
891 case PIPE_FORMAT_R32G32_UNORM
: return TRUE
;
892 case PIPE_FORMAT_R32_UNORM
: return TRUE
;
894 case PIPE_FORMAT_R32G32B32A32_SNORM
: return TRUE
;
895 case PIPE_FORMAT_R32G32B32_SNORM
: return TRUE
;
896 case PIPE_FORMAT_R32G32_SNORM
: return TRUE
;
897 case PIPE_FORMAT_R32_SNORM
: return TRUE
;
899 case PIPE_FORMAT_R16G16B16A16_USCALED
: return TRUE
;
900 case PIPE_FORMAT_R16G16B16_USCALED
: return TRUE
;
901 case PIPE_FORMAT_R16G16_USCALED
: return TRUE
;
902 case PIPE_FORMAT_R16_USCALED
: return TRUE
;
904 case PIPE_FORMAT_R16G16B16A16_SSCALED
: return TRUE
;
905 case PIPE_FORMAT_R16G16B16_SSCALED
: return TRUE
;
906 case PIPE_FORMAT_R16G16_SSCALED
: return TRUE
;
907 case PIPE_FORMAT_R16_SSCALED
: return TRUE
;
909 case PIPE_FORMAT_R16G16B16A16_UNORM
: return TRUE
;
910 case PIPE_FORMAT_R16G16B16_UNORM
: return TRUE
;
911 case PIPE_FORMAT_R16G16_UNORM
: return TRUE
;
912 case PIPE_FORMAT_R16_UNORM
: return TRUE
;
914 case PIPE_FORMAT_R16G16B16A16_SNORM
: return TRUE
;
915 case PIPE_FORMAT_R16G16B16_SNORM
: return TRUE
;
916 case PIPE_FORMAT_R16G16_SNORM
: return TRUE
;
917 case PIPE_FORMAT_R16_SNORM
: return TRUE
;
919 case PIPE_FORMAT_R8G8B8A8_USCALED
: return TRUE
;
920 case PIPE_FORMAT_R8G8B8_USCALED
: return TRUE
;
921 case PIPE_FORMAT_R8G8_USCALED
: return TRUE
;
922 case PIPE_FORMAT_R8_USCALED
: return TRUE
;
924 case PIPE_FORMAT_R8G8B8A8_SSCALED
: return TRUE
;
925 case PIPE_FORMAT_R8G8B8_SSCALED
: return TRUE
;
926 case PIPE_FORMAT_R8G8_SSCALED
: return TRUE
;
927 case PIPE_FORMAT_R8_SSCALED
: return TRUE
;
929 case PIPE_FORMAT_R8G8B8A8_UNORM
: return TRUE
;
930 case PIPE_FORMAT_R8G8B8_UNORM
: return TRUE
;
931 case PIPE_FORMAT_R8G8_UNORM
: return TRUE
;
932 case PIPE_FORMAT_R8_UNORM
: return TRUE
;
934 case PIPE_FORMAT_R8G8B8A8_SNORM
: return TRUE
;
935 case PIPE_FORMAT_R8G8B8_SNORM
: return TRUE
;
936 case PIPE_FORMAT_R8G8_SNORM
: return TRUE
;
937 case PIPE_FORMAT_R8_SNORM
: return TRUE
;
939 case PIPE_FORMAT_A8R8G8B8_UNORM
: return TRUE
;
940 case PIPE_FORMAT_B8G8R8A8_UNORM
: return TRUE
;
942 case PIPE_FORMAT_R32G32B32A32_UINT
: return TRUE
;
943 case PIPE_FORMAT_R32G32B32_UINT
: return TRUE
;
944 case PIPE_FORMAT_R32G32_UINT
: return TRUE
;
945 case PIPE_FORMAT_R32_UINT
: return TRUE
;
947 case PIPE_FORMAT_R16G16B16A16_UINT
: return TRUE
;
948 case PIPE_FORMAT_R16G16B16_UINT
: return TRUE
;
949 case PIPE_FORMAT_R16G16_UINT
: return TRUE
;
950 case PIPE_FORMAT_R16_UINT
: return TRUE
;
952 case PIPE_FORMAT_R8G8B8A8_UINT
: return TRUE
;
953 case PIPE_FORMAT_R8G8B8_UINT
: return TRUE
;
954 case PIPE_FORMAT_R8G8_UINT
: return TRUE
;
955 case PIPE_FORMAT_R8_UINT
: return TRUE
;
957 case PIPE_FORMAT_R32G32B32A32_SINT
: return TRUE
;
958 case PIPE_FORMAT_R32G32B32_SINT
: return TRUE
;
959 case PIPE_FORMAT_R32G32_SINT
: return TRUE
;
960 case PIPE_FORMAT_R32_SINT
: return TRUE
;
962 case PIPE_FORMAT_R16G16B16A16_SINT
: return TRUE
;
963 case PIPE_FORMAT_R16G16B16_SINT
: return TRUE
;
964 case PIPE_FORMAT_R16G16_SINT
: return TRUE
;
965 case PIPE_FORMAT_R16_SINT
: return TRUE
;
967 case PIPE_FORMAT_R8G8B8A8_SINT
: return TRUE
;
968 case PIPE_FORMAT_R8G8B8_SINT
: return TRUE
;
969 case PIPE_FORMAT_R8G8_SINT
: return TRUE
;
970 case PIPE_FORMAT_R8_SINT
: return TRUE
;
972 case PIPE_FORMAT_B10G10R10A2_UNORM
: return TRUE
;
973 case PIPE_FORMAT_B10G10R10A2_USCALED
: return TRUE
;
974 case PIPE_FORMAT_B10G10R10A2_SNORM
: return TRUE
;
975 case PIPE_FORMAT_B10G10R10A2_SSCALED
: return TRUE
;
977 case PIPE_FORMAT_R10G10B10A2_UNORM
: return TRUE
;
978 case PIPE_FORMAT_R10G10B10A2_USCALED
: return TRUE
;
979 case PIPE_FORMAT_R10G10B10A2_SNORM
: return TRUE
;
980 case PIPE_FORMAT_R10G10B10A2_SSCALED
: return TRUE
;
982 default: return FALSE
;