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