14a49301eSmrg/************************************************************************** 201e04c3fSmrg * 3af69d88dSmrg * Copyright 2007 VMware, Inc. 44a49301eSmrg * All Rights Reserved. 501e04c3fSmrg * 64a49301eSmrg * Permission is hereby granted, free of charge, to any person obtaining a 74a49301eSmrg * copy of this software and associated documentation files (the 84a49301eSmrg * "Software"), to deal in the Software without restriction, including 94a49301eSmrg * without limitation the rights to use, copy, modify, merge, publish, 104a49301eSmrg * distribute, sub license, and/or sell copies of the Software, and to 114a49301eSmrg * permit persons to whom the Software is furnished to do so, subject to 124a49301eSmrg * the following conditions: 1301e04c3fSmrg * 144a49301eSmrg * The above copyright notice and this permission notice (including the 154a49301eSmrg * next paragraph) shall be included in all copies or substantial portions 164a49301eSmrg * of the Software. 1701e04c3fSmrg * 184a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 194a49301eSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 204a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21af69d88dSmrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 224a49301eSmrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 234a49301eSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 244a49301eSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2501e04c3fSmrg * 264a49301eSmrg **************************************************************************/ 274a49301eSmrg 284a49301eSmrg /* 294a49301eSmrg * Authors: 30af69d88dSmrg * Keith Whitwell <keithw@vmware.com> 314a49301eSmrg */ 324a49301eSmrg 334a49301eSmrg#include "util/u_memory.h" 347ec681f3Smrg#include "util/format/u_format.h" 357ec681f3Smrg#include "util/half_float.h" 363464ebd5Sriastradh#include "util/u_math.h" 374a49301eSmrg#include "pipe/p_state.h" 384a49301eSmrg#include "translate.h" 394a49301eSmrg 404a49301eSmrg 414a49301eSmrg#define DRAW_DBG 0 424a49301eSmrg 43af69d88dSmrgtypedef void (*emit_func)(const void *attrib, void *ptr); 444a49301eSmrg 454a49301eSmrg 464a49301eSmrg 474a49301eSmrgstruct translate_generic { 484a49301eSmrg struct translate translate; 494a49301eSmrg 504a49301eSmrg struct { 51cdc920a0Smrg enum translate_element_type type; 52cdc920a0Smrg 537ec681f3Smrg void (*fetch)(void *restrict dst, const uint8_t *restrict src, 547ec681f3Smrg unsigned width); 554a49301eSmrg unsigned buffer; 564a49301eSmrg unsigned input_offset; 57cdc920a0Smrg unsigned instance_divisor; 584a49301eSmrg 594a49301eSmrg emit_func emit; 604a49301eSmrg unsigned output_offset; 6101e04c3fSmrg 623464ebd5Sriastradh const uint8_t *input_ptr; 634a49301eSmrg unsigned input_stride; 643464ebd5Sriastradh unsigned max_index; 653464ebd5Sriastradh 6601e04c3fSmrg /* this value is set to -1 if this is a normal element with 6701e04c3fSmrg * output_format != input_format: in this case, u_format is used 6801e04c3fSmrg * to do a full conversion 693464ebd5Sriastradh * 7001e04c3fSmrg * this value is set to the format size in bytes if 7101e04c3fSmrg * output_format == input_format or for 32-bit instance ids: 723464ebd5Sriastradh * in this case, memcpy is used to copy this amount of bytes 733464ebd5Sriastradh */ 743464ebd5Sriastradh int copy_size; 754a49301eSmrg 76af69d88dSmrg } attrib[TRANSLATE_MAX_ATTRIBS]; 774a49301eSmrg 784a49301eSmrg unsigned nr_attrib; 794a49301eSmrg}; 804a49301eSmrg 814a49301eSmrg 8201e04c3fSmrgstatic struct translate_generic * 8301e04c3fSmrgtranslate_generic(struct translate *translate) 844a49301eSmrg{ 854a49301eSmrg return (struct translate_generic *)translate; 864a49301eSmrg} 874a49301eSmrg 8801e04c3fSmrg 894a49301eSmrg/** 90af69d88dSmrg * Fetch a dword[4] vertex attribute from memory, doing format/type 914a49301eSmrg * conversion as needed. 924a49301eSmrg * 934a49301eSmrg * This is probably needed/dupliocated elsewhere, eg format 944a49301eSmrg * conversion, texture sampling etc. 954a49301eSmrg */ 9601e04c3fSmrg#define ATTRIB(NAME, SZ, SRCTYPE, DSTTYPE, TO) \ 974a49301eSmrgstatic void \ 98af69d88dSmrgemit_##NAME(const void *attrib, void *ptr) \ 994a49301eSmrg{ \ 1004a49301eSmrg unsigned i; \ 101af69d88dSmrg SRCTYPE *in = (SRCTYPE *)attrib; \ 102af69d88dSmrg DSTTYPE *out = (DSTTYPE *)ptr; \ 1034a49301eSmrg \ 1044a49301eSmrg for (i = 0; i < SZ; i++) { \ 105af69d88dSmrg out[i] = TO(in[i]); \ 1064a49301eSmrg } \ 1074a49301eSmrg} 1084a49301eSmrg 1094a49301eSmrg 1104a49301eSmrg#define TO_64_FLOAT(x) ((double) x) 1114a49301eSmrg#define TO_32_FLOAT(x) (x) 1127ec681f3Smrg#define TO_16_FLOAT(x) _mesa_float_to_half(x) 1134a49301eSmrg 1144a49301eSmrg#define TO_8_USCALED(x) ((unsigned char) x) 1154a49301eSmrg#define TO_16_USCALED(x) ((unsigned short) x) 1164a49301eSmrg#define TO_32_USCALED(x) ((unsigned int) x) 1174a49301eSmrg 1184a49301eSmrg#define TO_8_SSCALED(x) ((char) x) 1194a49301eSmrg#define TO_16_SSCALED(x) ((short) x) 1204a49301eSmrg#define TO_32_SSCALED(x) ((int) x) 1214a49301eSmrg 1224a49301eSmrg#define TO_8_UNORM(x) ((unsigned char) (x * 255.0f)) 1234a49301eSmrg#define TO_16_UNORM(x) ((unsigned short) (x * 65535.0f)) 1244a49301eSmrg#define TO_32_UNORM(x) ((unsigned int) (x * 4294967295.0f)) 1254a49301eSmrg 1264a49301eSmrg#define TO_8_SNORM(x) ((char) (x * 127.0f)) 1274a49301eSmrg#define TO_16_SNORM(x) ((short) (x * 32767.0f)) 1284a49301eSmrg#define TO_32_SNORM(x) ((int) (x * 2147483647.0f)) 1294a49301eSmrg 1304a49301eSmrg#define TO_32_FIXED(x) ((int) (x * 65536.0f)) 1314a49301eSmrg 132af69d88dSmrg#define TO_INT(x) (x) 133af69d88dSmrg 134af69d88dSmrg 13501e04c3fSmrgATTRIB(R64G64B64A64_FLOAT, 4, float, double, TO_64_FLOAT) 13601e04c3fSmrgATTRIB(R64G64B64_FLOAT, 3, float, double, TO_64_FLOAT) 13701e04c3fSmrgATTRIB(R64G64_FLOAT, 2, float, double, TO_64_FLOAT) 13801e04c3fSmrgATTRIB(R64_FLOAT, 1, float, double, TO_64_FLOAT) 13901e04c3fSmrg 14001e04c3fSmrgATTRIB(R32G32B32A32_FLOAT, 4, float, float, TO_32_FLOAT) 14101e04c3fSmrgATTRIB(R32G32B32_FLOAT, 3, float, float, TO_32_FLOAT) 14201e04c3fSmrgATTRIB(R32G32_FLOAT, 2, float, float, TO_32_FLOAT) 14301e04c3fSmrgATTRIB(R32_FLOAT, 1, float, float, TO_32_FLOAT) 14401e04c3fSmrg 14501e04c3fSmrgATTRIB(R16G16B16A16_FLOAT, 4, float, ushort, TO_16_FLOAT) 14601e04c3fSmrgATTRIB(R16G16B16_FLOAT, 3, float, ushort, TO_16_FLOAT) 14701e04c3fSmrgATTRIB(R16G16_FLOAT, 2, float, ushort, TO_16_FLOAT) 14801e04c3fSmrgATTRIB(R16_FLOAT, 1, float, ushort, TO_16_FLOAT) 14901e04c3fSmrg 15001e04c3fSmrgATTRIB(R32G32B32A32_USCALED, 4, float, unsigned, TO_32_USCALED) 15101e04c3fSmrgATTRIB(R32G32B32_USCALED, 3, float, unsigned, TO_32_USCALED) 15201e04c3fSmrgATTRIB(R32G32_USCALED, 2, float, unsigned, TO_32_USCALED) 15301e04c3fSmrgATTRIB(R32_USCALED, 1, float, unsigned, TO_32_USCALED) 15401e04c3fSmrg 15501e04c3fSmrgATTRIB(R32G32B32A32_SSCALED, 4, float, int, TO_32_SSCALED) 15601e04c3fSmrgATTRIB(R32G32B32_SSCALED, 3, float, int, TO_32_SSCALED) 15701e04c3fSmrgATTRIB(R32G32_SSCALED, 2, float, int, TO_32_SSCALED) 15801e04c3fSmrgATTRIB(R32_SSCALED, 1, float, int, TO_32_SSCALED) 15901e04c3fSmrg 16001e04c3fSmrgATTRIB(R32G32B32A32_UNORM, 4, float, unsigned, TO_32_UNORM) 16101e04c3fSmrgATTRIB(R32G32B32_UNORM, 3, float, unsigned, TO_32_UNORM) 16201e04c3fSmrgATTRIB(R32G32_UNORM, 2, float, unsigned, TO_32_UNORM) 16301e04c3fSmrgATTRIB(R32_UNORM, 1, float, unsigned, TO_32_UNORM) 16401e04c3fSmrg 16501e04c3fSmrgATTRIB(R32G32B32A32_SNORM, 4, float, int, TO_32_SNORM) 16601e04c3fSmrgATTRIB(R32G32B32_SNORM, 3, float, int, TO_32_SNORM) 16701e04c3fSmrgATTRIB(R32G32_SNORM, 2, float, int, TO_32_SNORM) 16801e04c3fSmrgATTRIB(R32_SNORM, 1, float, int, TO_32_SNORM) 16901e04c3fSmrg 17001e04c3fSmrgATTRIB(R16G16B16A16_USCALED, 4, float, ushort, TO_16_USCALED) 17101e04c3fSmrgATTRIB(R16G16B16_USCALED, 3, float, ushort, TO_16_USCALED) 17201e04c3fSmrgATTRIB(R16G16_USCALED, 2, float, ushort, TO_16_USCALED) 17301e04c3fSmrgATTRIB(R16_USCALED, 1, float, ushort, TO_16_USCALED) 17401e04c3fSmrg 17501e04c3fSmrgATTRIB(R16G16B16A16_SSCALED, 4, float, short, TO_16_SSCALED) 17601e04c3fSmrgATTRIB(R16G16B16_SSCALED, 3, float, short, TO_16_SSCALED) 17701e04c3fSmrgATTRIB(R16G16_SSCALED, 2, float, short, TO_16_SSCALED) 17801e04c3fSmrgATTRIB(R16_SSCALED, 1, float, short, TO_16_SSCALED) 17901e04c3fSmrg 18001e04c3fSmrgATTRIB(R16G16B16A16_UNORM, 4, float, ushort, TO_16_UNORM) 18101e04c3fSmrgATTRIB(R16G16B16_UNORM, 3, float, ushort, TO_16_UNORM) 18201e04c3fSmrgATTRIB(R16G16_UNORM, 2, float, ushort, TO_16_UNORM) 18301e04c3fSmrgATTRIB(R16_UNORM, 1, float, ushort, TO_16_UNORM) 18401e04c3fSmrg 18501e04c3fSmrgATTRIB(R16G16B16A16_SNORM, 4, float, short, TO_16_SNORM) 18601e04c3fSmrgATTRIB(R16G16B16_SNORM, 3, float, short, TO_16_SNORM) 18701e04c3fSmrgATTRIB(R16G16_SNORM, 2, float, short, TO_16_SNORM) 18801e04c3fSmrgATTRIB(R16_SNORM, 1, float, short, TO_16_SNORM) 18901e04c3fSmrg 19001e04c3fSmrgATTRIB(R8G8B8A8_USCALED, 4, float, ubyte, TO_8_USCALED) 19101e04c3fSmrgATTRIB(R8G8B8_USCALED, 3, float, ubyte, TO_8_USCALED) 19201e04c3fSmrgATTRIB(R8G8_USCALED, 2, float, ubyte, TO_8_USCALED) 19301e04c3fSmrgATTRIB(R8_USCALED, 1, float, ubyte, TO_8_USCALED) 19401e04c3fSmrg 19501e04c3fSmrgATTRIB(R8G8B8A8_SSCALED, 4, float, char, TO_8_SSCALED) 19601e04c3fSmrgATTRIB(R8G8B8_SSCALED, 3, float, char, TO_8_SSCALED) 19701e04c3fSmrgATTRIB(R8G8_SSCALED, 2, float, char, TO_8_SSCALED) 19801e04c3fSmrgATTRIB(R8_SSCALED, 1, float, char, TO_8_SSCALED) 19901e04c3fSmrg 20001e04c3fSmrgATTRIB(R8G8B8A8_UNORM, 4, float, ubyte, TO_8_UNORM) 20101e04c3fSmrgATTRIB(R8G8B8_UNORM, 3, float, ubyte, TO_8_UNORM) 20201e04c3fSmrgATTRIB(R8G8_UNORM, 2, float, ubyte, TO_8_UNORM) 20301e04c3fSmrgATTRIB(R8_UNORM, 1, float, ubyte, TO_8_UNORM) 20401e04c3fSmrg 20501e04c3fSmrgATTRIB(R8G8B8A8_SNORM, 4, float, char, TO_8_SNORM) 20601e04c3fSmrgATTRIB(R8G8B8_SNORM, 3, float, char, TO_8_SNORM) 20701e04c3fSmrgATTRIB(R8G8_SNORM, 2, float, char, TO_8_SNORM) 20801e04c3fSmrgATTRIB(R8_SNORM, 1, float, char, TO_8_SNORM) 20901e04c3fSmrg 21001e04c3fSmrgATTRIB(R32G32B32A32_UINT, 4, uint32_t, unsigned, TO_INT) 21101e04c3fSmrgATTRIB(R32G32B32_UINT, 3, uint32_t, unsigned, TO_INT) 21201e04c3fSmrgATTRIB(R32G32_UINT, 2, uint32_t, unsigned, TO_INT) 21301e04c3fSmrgATTRIB(R32_UINT, 1, uint32_t, unsigned, TO_INT) 21401e04c3fSmrg 21501e04c3fSmrgATTRIB(R16G16B16A16_UINT, 4, uint32_t, ushort, TO_INT) 21601e04c3fSmrgATTRIB(R16G16B16_UINT, 3, uint32_t, ushort, TO_INT) 21701e04c3fSmrgATTRIB(R16G16_UINT, 2, uint32_t, ushort, TO_INT) 21801e04c3fSmrgATTRIB(R16_UINT, 1, uint32_t, ushort, TO_INT) 21901e04c3fSmrg 22001e04c3fSmrgATTRIB(R8G8B8A8_UINT, 4, uint32_t, ubyte, TO_INT) 22101e04c3fSmrgATTRIB(R8G8B8_UINT, 3, uint32_t, ubyte, TO_INT) 22201e04c3fSmrgATTRIB(R8G8_UINT, 2, uint32_t, ubyte, TO_INT) 22301e04c3fSmrgATTRIB(R8_UINT, 1, uint32_t, ubyte, TO_INT) 22401e04c3fSmrg 22501e04c3fSmrgATTRIB(R32G32B32A32_SINT, 4, int32_t, int, TO_INT) 22601e04c3fSmrgATTRIB(R32G32B32_SINT, 3, int32_t, int, TO_INT) 22701e04c3fSmrgATTRIB(R32G32_SINT, 2, int32_t, int, TO_INT) 22801e04c3fSmrgATTRIB(R32_SINT, 1, int32_t, int, TO_INT) 22901e04c3fSmrg 23001e04c3fSmrgATTRIB(R16G16B16A16_SINT, 4, int32_t, short, TO_INT) 23101e04c3fSmrgATTRIB(R16G16B16_SINT, 3, int32_t, short, TO_INT) 23201e04c3fSmrgATTRIB(R16G16_SINT, 2, int32_t, short, TO_INT) 23301e04c3fSmrgATTRIB(R16_SINT, 1, int32_t, short, TO_INT) 23401e04c3fSmrg 23501e04c3fSmrgATTRIB(R8G8B8A8_SINT, 4, int32_t, char, TO_INT) 23601e04c3fSmrgATTRIB(R8G8B8_SINT, 3, int32_t, char, TO_INT) 23701e04c3fSmrgATTRIB(R8G8_SINT, 2, int32_t, char, TO_INT) 23801e04c3fSmrgATTRIB(R8_SINT, 1, int32_t, char, TO_INT) 2394a49301eSmrg 2404a49301eSmrgstatic void 24101e04c3fSmrgemit_A8R8G8B8_UNORM(const void *attrib, void *ptr) 2424a49301eSmrg{ 243af69d88dSmrg float *in = (float *)attrib; 2443464ebd5Sriastradh ubyte *out = (ubyte *)ptr; 245af69d88dSmrg out[0] = TO_8_UNORM(in[3]); 246af69d88dSmrg out[1] = TO_8_UNORM(in[0]); 247af69d88dSmrg out[2] = TO_8_UNORM(in[1]); 248af69d88dSmrg out[3] = TO_8_UNORM(in[2]); 2494a49301eSmrg} 2504a49301eSmrg 2514a49301eSmrgstatic void 25201e04c3fSmrgemit_B8G8R8A8_UNORM(const void *attrib, void *ptr) 2534a49301eSmrg{ 254af69d88dSmrg float *in = (float *)attrib; 2554a49301eSmrg ubyte *out = (ubyte *)ptr; 256af69d88dSmrg out[2] = TO_8_UNORM(in[0]); 257af69d88dSmrg out[1] = TO_8_UNORM(in[1]); 258af69d88dSmrg out[0] = TO_8_UNORM(in[2]); 259af69d88dSmrg out[3] = TO_8_UNORM(in[3]); 260af69d88dSmrg} 261af69d88dSmrg 262af69d88dSmrgstatic void 26301e04c3fSmrgemit_B10G10R10A2_UNORM(const void *attrib, void *ptr) 264af69d88dSmrg{ 265af69d88dSmrg float *src = (float *)ptr; 266af69d88dSmrg uint32_t value = 0; 267af69d88dSmrg value |= ((uint32_t)(CLAMP(src[2], 0, 1) * 0x3ff)) & 0x3ff; 268af69d88dSmrg value |= (((uint32_t)(CLAMP(src[1], 0, 1) * 0x3ff)) & 0x3ff) << 10; 269af69d88dSmrg value |= (((uint32_t)(CLAMP(src[0], 0, 1) * 0x3ff)) & 0x3ff) << 20; 270af69d88dSmrg value |= ((uint32_t)(CLAMP(src[3], 0, 1) * 0x3)) << 30; 27101e04c3fSmrg *(uint32_t *)attrib = util_le32_to_cpu(value); 272af69d88dSmrg} 273af69d88dSmrg 274af69d88dSmrgstatic void 27501e04c3fSmrgemit_B10G10R10A2_USCALED(const void *attrib, void *ptr) 276af69d88dSmrg{ 277af69d88dSmrg float *src = (float *)ptr; 278af69d88dSmrg uint32_t value = 0; 279af69d88dSmrg value |= ((uint32_t)CLAMP(src[2], 0, 1023)) & 0x3ff; 280af69d88dSmrg value |= (((uint32_t)CLAMP(src[1], 0, 1023)) & 0x3ff) << 10; 281af69d88dSmrg value |= (((uint32_t)CLAMP(src[0], 0, 1023)) & 0x3ff) << 20; 282af69d88dSmrg value |= ((uint32_t)CLAMP(src[3], 0, 3)) << 30; 28301e04c3fSmrg *(uint32_t *)attrib = util_le32_to_cpu(value); 284af69d88dSmrg} 285af69d88dSmrg 286af69d88dSmrgstatic void 28701e04c3fSmrgemit_B10G10R10A2_SNORM(const void *attrib, void *ptr) 288af69d88dSmrg{ 289af69d88dSmrg float *src = (float *)ptr; 290af69d88dSmrg uint32_t value = 0; 291af69d88dSmrg value |= (uint32_t)(((uint32_t)(CLAMP(src[2], -1, 1) * 0x1ff)) & 0x3ff) ; 292af69d88dSmrg value |= (uint32_t)((((uint32_t)(CLAMP(src[1], -1, 1) * 0x1ff)) & 0x3ff) << 10) ; 293af69d88dSmrg value |= (uint32_t)((((uint32_t)(CLAMP(src[0], -1, 1) * 0x1ff)) & 0x3ff) << 20) ; 294af69d88dSmrg value |= (uint32_t)(((uint32_t)(CLAMP(src[3], -1, 1) * 0x1)) << 30) ; 29501e04c3fSmrg *(uint32_t *)attrib = util_le32_to_cpu(value); 296af69d88dSmrg} 297af69d88dSmrg 298af69d88dSmrgstatic void 29901e04c3fSmrgemit_B10G10R10A2_SSCALED(const void *attrib, void *ptr) 300af69d88dSmrg{ 301af69d88dSmrg float *src = (float *)ptr; 302af69d88dSmrg uint32_t value = 0; 303af69d88dSmrg value |= (uint32_t)(((uint32_t)CLAMP(src[2], -512, 511)) & 0x3ff) ; 304af69d88dSmrg value |= (uint32_t)((((uint32_t)CLAMP(src[1], -512, 511)) & 0x3ff) << 10) ; 305af69d88dSmrg value |= (uint32_t)((((uint32_t)CLAMP(src[0], -512, 511)) & 0x3ff) << 20) ; 306af69d88dSmrg value |= (uint32_t)(((uint32_t)CLAMP(src[3], -2, 1)) << 30) ; 30701e04c3fSmrg *(uint32_t *)attrib = util_le32_to_cpu(value); 308af69d88dSmrg} 309af69d88dSmrg 310af69d88dSmrgstatic void 31101e04c3fSmrgemit_R10G10B10A2_UNORM(const void *attrib, void *ptr) 312af69d88dSmrg{ 313af69d88dSmrg float *src = (float *)ptr; 314af69d88dSmrg uint32_t value = 0; 315af69d88dSmrg value |= ((uint32_t)(CLAMP(src[0], 0, 1) * 0x3ff)) & 0x3ff; 316af69d88dSmrg value |= (((uint32_t)(CLAMP(src[1], 0, 1) * 0x3ff)) & 0x3ff) << 10; 317af69d88dSmrg value |= (((uint32_t)(CLAMP(src[2], 0, 1) * 0x3ff)) & 0x3ff) << 20; 318af69d88dSmrg value |= ((uint32_t)(CLAMP(src[3], 0, 1) * 0x3)) << 30; 31901e04c3fSmrg *(uint32_t *)attrib = util_le32_to_cpu(value); 320af69d88dSmrg} 321af69d88dSmrg 322af69d88dSmrgstatic void 32301e04c3fSmrgemit_R10G10B10A2_USCALED(const void *attrib, void *ptr) 324af69d88dSmrg{ 325af69d88dSmrg float *src = (float *)ptr; 326af69d88dSmrg uint32_t value = 0; 327af69d88dSmrg value |= ((uint32_t)CLAMP(src[0], 0, 1023)) & 0x3ff; 328af69d88dSmrg value |= (((uint32_t)CLAMP(src[1], 0, 1023)) & 0x3ff) << 10; 329af69d88dSmrg value |= (((uint32_t)CLAMP(src[2], 0, 1023)) & 0x3ff) << 20; 330af69d88dSmrg value |= ((uint32_t)CLAMP(src[3], 0, 3)) << 30; 33101e04c3fSmrg *(uint32_t *)attrib = util_le32_to_cpu(value); 332af69d88dSmrg} 333af69d88dSmrg 334af69d88dSmrgstatic void 33501e04c3fSmrgemit_R10G10B10A2_SNORM(const void *attrib, void *ptr) 336af69d88dSmrg{ 337af69d88dSmrg float *src = (float *)ptr; 338af69d88dSmrg uint32_t value = 0; 339af69d88dSmrg value |= (uint32_t)(((uint32_t)(CLAMP(src[0], -1, 1) * 0x1ff)) & 0x3ff) ; 340af69d88dSmrg value |= (uint32_t)((((uint32_t)(CLAMP(src[1], -1, 1) * 0x1ff)) & 0x3ff) << 10) ; 341af69d88dSmrg value |= (uint32_t)((((uint32_t)(CLAMP(src[2], -1, 1) * 0x1ff)) & 0x3ff) << 20) ; 342af69d88dSmrg value |= (uint32_t)(((uint32_t)(CLAMP(src[3], -1, 1) * 0x1)) << 30) ; 34301e04c3fSmrg *(uint32_t *)attrib = util_le32_to_cpu(value); 344af69d88dSmrg} 345af69d88dSmrg 346af69d88dSmrgstatic void 34701e04c3fSmrgemit_R10G10B10A2_SSCALED(const void *attrib, void *ptr) 348af69d88dSmrg{ 349af69d88dSmrg float *src = (float *)ptr; 350af69d88dSmrg uint32_t value = 0; 351af69d88dSmrg value |= (uint32_t)(((uint32_t)CLAMP(src[0], -512, 511)) & 0x3ff) ; 352af69d88dSmrg value |= (uint32_t)((((uint32_t)CLAMP(src[1], -512, 511)) & 0x3ff) << 10) ; 353af69d88dSmrg value |= (uint32_t)((((uint32_t)CLAMP(src[2], -512, 511)) & 0x3ff) << 20) ; 354af69d88dSmrg value |= (uint32_t)(((uint32_t)CLAMP(src[3], -2, 1)) << 30) ; 35501e04c3fSmrg *(uint32_t *)attrib = util_le32_to_cpu(value); 3564a49301eSmrg} 3574a49301eSmrg 35801e04c3fSmrgstatic void 35901e04c3fSmrgemit_NULL(const void *attrib, void *ptr) 3604a49301eSmrg{ 3614a49301eSmrg /* do nothing is the only sensible option */ 3624a49301eSmrg} 3634a49301eSmrg 36401e04c3fSmrgstatic emit_func 36501e04c3fSmrgget_emit_func(enum pipe_format format) 3664a49301eSmrg{ 3674a49301eSmrg switch (format) { 3684a49301eSmrg case PIPE_FORMAT_R64_FLOAT: 3694a49301eSmrg return &emit_R64_FLOAT; 3704a49301eSmrg case PIPE_FORMAT_R64G64_FLOAT: 3714a49301eSmrg return &emit_R64G64_FLOAT; 3724a49301eSmrg case PIPE_FORMAT_R64G64B64_FLOAT: 3734a49301eSmrg return &emit_R64G64B64_FLOAT; 3744a49301eSmrg case PIPE_FORMAT_R64G64B64A64_FLOAT: 3754a49301eSmrg return &emit_R64G64B64A64_FLOAT; 3764a49301eSmrg 3774a49301eSmrg case PIPE_FORMAT_R32_FLOAT: 3784a49301eSmrg return &emit_R32_FLOAT; 3794a49301eSmrg case PIPE_FORMAT_R32G32_FLOAT: 3804a49301eSmrg return &emit_R32G32_FLOAT; 3814a49301eSmrg case PIPE_FORMAT_R32G32B32_FLOAT: 3824a49301eSmrg return &emit_R32G32B32_FLOAT; 3834a49301eSmrg case PIPE_FORMAT_R32G32B32A32_FLOAT: 3844a49301eSmrg return &emit_R32G32B32A32_FLOAT; 3854a49301eSmrg 386af69d88dSmrg case PIPE_FORMAT_R16_FLOAT: 387af69d88dSmrg return &emit_R16_FLOAT; 388af69d88dSmrg case PIPE_FORMAT_R16G16_FLOAT: 389af69d88dSmrg return &emit_R16G16_FLOAT; 390af69d88dSmrg case PIPE_FORMAT_R16G16B16_FLOAT: 391af69d88dSmrg return &emit_R16G16B16_FLOAT; 392af69d88dSmrg case PIPE_FORMAT_R16G16B16A16_FLOAT: 393af69d88dSmrg return &emit_R16G16B16A16_FLOAT; 394af69d88dSmrg 3954a49301eSmrg case PIPE_FORMAT_R32_UNORM: 3964a49301eSmrg return &emit_R32_UNORM; 3974a49301eSmrg case PIPE_FORMAT_R32G32_UNORM: 3984a49301eSmrg return &emit_R32G32_UNORM; 3994a49301eSmrg case PIPE_FORMAT_R32G32B32_UNORM: 4004a49301eSmrg return &emit_R32G32B32_UNORM; 4014a49301eSmrg case PIPE_FORMAT_R32G32B32A32_UNORM: 4024a49301eSmrg return &emit_R32G32B32A32_UNORM; 4034a49301eSmrg 4044a49301eSmrg case PIPE_FORMAT_R32_USCALED: 4054a49301eSmrg return &emit_R32_USCALED; 4064a49301eSmrg case PIPE_FORMAT_R32G32_USCALED: 4074a49301eSmrg return &emit_R32G32_USCALED; 4084a49301eSmrg case PIPE_FORMAT_R32G32B32_USCALED: 4094a49301eSmrg return &emit_R32G32B32_USCALED; 4104a49301eSmrg case PIPE_FORMAT_R32G32B32A32_USCALED: 4114a49301eSmrg return &emit_R32G32B32A32_USCALED; 4124a49301eSmrg 4134a49301eSmrg case PIPE_FORMAT_R32_SNORM: 4144a49301eSmrg return &emit_R32_SNORM; 4154a49301eSmrg case PIPE_FORMAT_R32G32_SNORM: 4164a49301eSmrg return &emit_R32G32_SNORM; 4174a49301eSmrg case PIPE_FORMAT_R32G32B32_SNORM: 4184a49301eSmrg return &emit_R32G32B32_SNORM; 4194a49301eSmrg case PIPE_FORMAT_R32G32B32A32_SNORM: 4204a49301eSmrg return &emit_R32G32B32A32_SNORM; 4214a49301eSmrg 4224a49301eSmrg case PIPE_FORMAT_R32_SSCALED: 4234a49301eSmrg return &emit_R32_SSCALED; 4244a49301eSmrg case PIPE_FORMAT_R32G32_SSCALED: 4254a49301eSmrg return &emit_R32G32_SSCALED; 4264a49301eSmrg case PIPE_FORMAT_R32G32B32_SSCALED: 4274a49301eSmrg return &emit_R32G32B32_SSCALED; 4284a49301eSmrg case PIPE_FORMAT_R32G32B32A32_SSCALED: 4294a49301eSmrg return &emit_R32G32B32A32_SSCALED; 4304a49301eSmrg 4314a49301eSmrg case PIPE_FORMAT_R16_UNORM: 4324a49301eSmrg return &emit_R16_UNORM; 4334a49301eSmrg case PIPE_FORMAT_R16G16_UNORM: 4344a49301eSmrg return &emit_R16G16_UNORM; 4354a49301eSmrg case PIPE_FORMAT_R16G16B16_UNORM: 4364a49301eSmrg return &emit_R16G16B16_UNORM; 4374a49301eSmrg case PIPE_FORMAT_R16G16B16A16_UNORM: 4384a49301eSmrg return &emit_R16G16B16A16_UNORM; 4394a49301eSmrg 4404a49301eSmrg case PIPE_FORMAT_R16_USCALED: 4414a49301eSmrg return &emit_R16_USCALED; 4424a49301eSmrg case PIPE_FORMAT_R16G16_USCALED: 4434a49301eSmrg return &emit_R16G16_USCALED; 4444a49301eSmrg case PIPE_FORMAT_R16G16B16_USCALED: 4454a49301eSmrg return &emit_R16G16B16_USCALED; 4464a49301eSmrg case PIPE_FORMAT_R16G16B16A16_USCALED: 4474a49301eSmrg return &emit_R16G16B16A16_USCALED; 4484a49301eSmrg 4494a49301eSmrg case PIPE_FORMAT_R16_SNORM: 4504a49301eSmrg return &emit_R16_SNORM; 4514a49301eSmrg case PIPE_FORMAT_R16G16_SNORM: 4524a49301eSmrg return &emit_R16G16_SNORM; 4534a49301eSmrg case PIPE_FORMAT_R16G16B16_SNORM: 4544a49301eSmrg return &emit_R16G16B16_SNORM; 4554a49301eSmrg case PIPE_FORMAT_R16G16B16A16_SNORM: 4564a49301eSmrg return &emit_R16G16B16A16_SNORM; 4574a49301eSmrg 4584a49301eSmrg case PIPE_FORMAT_R16_SSCALED: 4594a49301eSmrg return &emit_R16_SSCALED; 4604a49301eSmrg case PIPE_FORMAT_R16G16_SSCALED: 4614a49301eSmrg return &emit_R16G16_SSCALED; 4624a49301eSmrg case PIPE_FORMAT_R16G16B16_SSCALED: 4634a49301eSmrg return &emit_R16G16B16_SSCALED; 4644a49301eSmrg case PIPE_FORMAT_R16G16B16A16_SSCALED: 4654a49301eSmrg return &emit_R16G16B16A16_SSCALED; 4664a49301eSmrg 4674a49301eSmrg case PIPE_FORMAT_R8_UNORM: 4684a49301eSmrg return &emit_R8_UNORM; 4694a49301eSmrg case PIPE_FORMAT_R8G8_UNORM: 4704a49301eSmrg return &emit_R8G8_UNORM; 4714a49301eSmrg case PIPE_FORMAT_R8G8B8_UNORM: 4724a49301eSmrg return &emit_R8G8B8_UNORM; 4734a49301eSmrg case PIPE_FORMAT_R8G8B8A8_UNORM: 4744a49301eSmrg return &emit_R8G8B8A8_UNORM; 4754a49301eSmrg 4764a49301eSmrg case PIPE_FORMAT_R8_USCALED: 4774a49301eSmrg return &emit_R8_USCALED; 4784a49301eSmrg case PIPE_FORMAT_R8G8_USCALED: 4794a49301eSmrg return &emit_R8G8_USCALED; 4804a49301eSmrg case PIPE_FORMAT_R8G8B8_USCALED: 4814a49301eSmrg return &emit_R8G8B8_USCALED; 4824a49301eSmrg case PIPE_FORMAT_R8G8B8A8_USCALED: 4834a49301eSmrg return &emit_R8G8B8A8_USCALED; 4844a49301eSmrg 4854a49301eSmrg case PIPE_FORMAT_R8_SNORM: 4864a49301eSmrg return &emit_R8_SNORM; 4874a49301eSmrg case PIPE_FORMAT_R8G8_SNORM: 4884a49301eSmrg return &emit_R8G8_SNORM; 4894a49301eSmrg case PIPE_FORMAT_R8G8B8_SNORM: 4904a49301eSmrg return &emit_R8G8B8_SNORM; 4914a49301eSmrg case PIPE_FORMAT_R8G8B8A8_SNORM: 4924a49301eSmrg return &emit_R8G8B8A8_SNORM; 4934a49301eSmrg 4944a49301eSmrg case PIPE_FORMAT_R8_SSCALED: 4954a49301eSmrg return &emit_R8_SSCALED; 4964a49301eSmrg case PIPE_FORMAT_R8G8_SSCALED: 4974a49301eSmrg return &emit_R8G8_SSCALED; 4984a49301eSmrg case PIPE_FORMAT_R8G8B8_SSCALED: 4994a49301eSmrg return &emit_R8G8B8_SSCALED; 5004a49301eSmrg case PIPE_FORMAT_R8G8B8A8_SSCALED: 5014a49301eSmrg return &emit_R8G8B8A8_SSCALED; 5024a49301eSmrg 503cdc920a0Smrg case PIPE_FORMAT_B8G8R8A8_UNORM: 5043464ebd5Sriastradh return &emit_B8G8R8A8_UNORM; 5054a49301eSmrg 506cdc920a0Smrg case PIPE_FORMAT_A8R8G8B8_UNORM: 5073464ebd5Sriastradh return &emit_A8R8G8B8_UNORM; 5084a49301eSmrg 509af69d88dSmrg case PIPE_FORMAT_R32_UINT: 510af69d88dSmrg return &emit_R32_UINT; 511af69d88dSmrg case PIPE_FORMAT_R32G32_UINT: 512af69d88dSmrg return &emit_R32G32_UINT; 513af69d88dSmrg case PIPE_FORMAT_R32G32B32_UINT: 514af69d88dSmrg return &emit_R32G32B32_UINT; 515af69d88dSmrg case PIPE_FORMAT_R32G32B32A32_UINT: 516af69d88dSmrg return &emit_R32G32B32A32_UINT; 517af69d88dSmrg 518af69d88dSmrg case PIPE_FORMAT_R16_UINT: 519af69d88dSmrg return &emit_R16_UINT; 520af69d88dSmrg case PIPE_FORMAT_R16G16_UINT: 521af69d88dSmrg return &emit_R16G16_UINT; 522af69d88dSmrg case PIPE_FORMAT_R16G16B16_UINT: 523af69d88dSmrg return &emit_R16G16B16_UINT; 524af69d88dSmrg case PIPE_FORMAT_R16G16B16A16_UINT: 525af69d88dSmrg return &emit_R16G16B16A16_UINT; 526af69d88dSmrg 527af69d88dSmrg case PIPE_FORMAT_R8_UINT: 528af69d88dSmrg return &emit_R8_UINT; 529af69d88dSmrg case PIPE_FORMAT_R8G8_UINT: 530af69d88dSmrg return &emit_R8G8_UINT; 531af69d88dSmrg case PIPE_FORMAT_R8G8B8_UINT: 532af69d88dSmrg return &emit_R8G8B8_UINT; 533af69d88dSmrg case PIPE_FORMAT_R8G8B8A8_UINT: 534af69d88dSmrg return &emit_R8G8B8A8_UINT; 535af69d88dSmrg 536af69d88dSmrg case PIPE_FORMAT_R32_SINT: 537af69d88dSmrg return &emit_R32_SINT; 538af69d88dSmrg case PIPE_FORMAT_R32G32_SINT: 539af69d88dSmrg return &emit_R32G32_SINT; 540af69d88dSmrg case PIPE_FORMAT_R32G32B32_SINT: 541af69d88dSmrg return &emit_R32G32B32_SINT; 542af69d88dSmrg case PIPE_FORMAT_R32G32B32A32_SINT: 543af69d88dSmrg return &emit_R32G32B32A32_SINT; 544af69d88dSmrg 545af69d88dSmrg case PIPE_FORMAT_R16_SINT: 546af69d88dSmrg return &emit_R16_SINT; 547af69d88dSmrg case PIPE_FORMAT_R16G16_SINT: 548af69d88dSmrg return &emit_R16G16_SINT; 549af69d88dSmrg case PIPE_FORMAT_R16G16B16_SINT: 550af69d88dSmrg return &emit_R16G16B16_SINT; 551af69d88dSmrg case PIPE_FORMAT_R16G16B16A16_SINT: 552af69d88dSmrg return &emit_R16G16B16A16_SINT; 553af69d88dSmrg 554af69d88dSmrg case PIPE_FORMAT_R8_SINT: 555af69d88dSmrg return &emit_R8_SINT; 556af69d88dSmrg case PIPE_FORMAT_R8G8_SINT: 557af69d88dSmrg return &emit_R8G8_SINT; 558af69d88dSmrg case PIPE_FORMAT_R8G8B8_SINT: 559af69d88dSmrg return &emit_R8G8B8_SINT; 560af69d88dSmrg case PIPE_FORMAT_R8G8B8A8_SINT: 561af69d88dSmrg return &emit_R8G8B8A8_SINT; 562af69d88dSmrg 563af69d88dSmrg case PIPE_FORMAT_B10G10R10A2_UNORM: 564af69d88dSmrg return &emit_B10G10R10A2_UNORM; 565af69d88dSmrg case PIPE_FORMAT_B10G10R10A2_USCALED: 566af69d88dSmrg return &emit_B10G10R10A2_USCALED; 567af69d88dSmrg case PIPE_FORMAT_B10G10R10A2_SNORM: 568af69d88dSmrg return &emit_B10G10R10A2_SNORM; 569af69d88dSmrg case PIPE_FORMAT_B10G10R10A2_SSCALED: 570af69d88dSmrg return &emit_B10G10R10A2_SSCALED; 571af69d88dSmrg 572af69d88dSmrg case PIPE_FORMAT_R10G10B10A2_UNORM: 573af69d88dSmrg return &emit_R10G10B10A2_UNORM; 574af69d88dSmrg case PIPE_FORMAT_R10G10B10A2_USCALED: 575af69d88dSmrg return &emit_R10G10B10A2_USCALED; 576af69d88dSmrg case PIPE_FORMAT_R10G10B10A2_SNORM: 577af69d88dSmrg return &emit_R10G10B10A2_SNORM; 578af69d88dSmrg case PIPE_FORMAT_R10G10B10A2_SSCALED: 579af69d88dSmrg return &emit_R10G10B10A2_SSCALED; 580af69d88dSmrg 5814a49301eSmrg default: 58201e04c3fSmrg assert(0); 5834a49301eSmrg return &emit_NULL; 5844a49301eSmrg } 5854a49301eSmrg} 5864a49301eSmrg 58701e04c3fSmrgstatic ALWAYS_INLINE void PIPE_CDECL 58801e04c3fSmrggeneric_run_one(struct translate_generic *tg, 58901e04c3fSmrg unsigned elt, 59001e04c3fSmrg unsigned start_instance, 59101e04c3fSmrg unsigned instance_id, 59201e04c3fSmrg void *vert) 5933464ebd5Sriastradh{ 5943464ebd5Sriastradh unsigned nr_attrs = tg->nr_attrib; 5953464ebd5Sriastradh unsigned attr; 5964a49301eSmrg 5973464ebd5Sriastradh for (attr = 0; attr < nr_attrs; attr++) { 5983464ebd5Sriastradh float data[4]; 5993464ebd5Sriastradh uint8_t *dst = (uint8_t *)vert + tg->attrib[attr].output_offset; 6003464ebd5Sriastradh 6013464ebd5Sriastradh if (tg->attrib[attr].type == TRANSLATE_ELEMENT_NORMAL) { 6023464ebd5Sriastradh const uint8_t *src; 6033464ebd5Sriastradh unsigned index; 6043464ebd5Sriastradh int copy_size; 6053464ebd5Sriastradh 6063464ebd5Sriastradh if (tg->attrib[attr].instance_divisor) { 607af69d88dSmrg index = start_instance; 608af69d88dSmrg index += (instance_id / tg->attrib[attr].instance_divisor); 6093464ebd5Sriastradh /* XXX we need to clamp the index here too, but to a 6103464ebd5Sriastradh * per-array max value, not the draw->pt.max_index value 6113464ebd5Sriastradh * that's being given to us via translate->set_buffer(). 6123464ebd5Sriastradh */ 6133464ebd5Sriastradh } 6143464ebd5Sriastradh else { 6153464ebd5Sriastradh index = elt; 6163464ebd5Sriastradh /* clamp to avoid going out of bounds */ 6173464ebd5Sriastradh index = MIN2(index, tg->attrib[attr].max_index); 6183464ebd5Sriastradh } 6193464ebd5Sriastradh 6203464ebd5Sriastradh src = tg->attrib[attr].input_ptr + 621af69d88dSmrg (ptrdiff_t)tg->attrib[attr].input_stride * index; 6223464ebd5Sriastradh 6233464ebd5Sriastradh copy_size = tg->attrib[attr].copy_size; 62401e04c3fSmrg if (likely(copy_size >= 0)) { 6253464ebd5Sriastradh memcpy(dst, src, copy_size); 62601e04c3fSmrg } else { 6277ec681f3Smrg tg->attrib[attr].fetch(data, src, 1); 6283464ebd5Sriastradh 6293464ebd5Sriastradh if (0) 6303464ebd5Sriastradh debug_printf("Fetch linear attr %d from %p stride %d index %d: " 6313464ebd5Sriastradh " %f, %f, %f, %f \n", 6323464ebd5Sriastradh attr, 6333464ebd5Sriastradh tg->attrib[attr].input_ptr, 6343464ebd5Sriastradh tg->attrib[attr].input_stride, 6353464ebd5Sriastradh index, 6363464ebd5Sriastradh data[0], data[1],data[2], data[3]); 6373464ebd5Sriastradh 63801e04c3fSmrg tg->attrib[attr].emit(data, dst); 6393464ebd5Sriastradh } 6403464ebd5Sriastradh } else { 64101e04c3fSmrg if (likely(tg->attrib[attr].copy_size >= 0)) { 6423464ebd5Sriastradh memcpy(data, &instance_id, 4); 64301e04c3fSmrg } else { 6443464ebd5Sriastradh data[0] = (float)instance_id; 64501e04c3fSmrg tg->attrib[attr].emit(data, dst); 6463464ebd5Sriastradh } 6473464ebd5Sriastradh } 6483464ebd5Sriastradh } 6493464ebd5Sriastradh} 6504a49301eSmrg 6514a49301eSmrg/** 6524a49301eSmrg * Fetch vertex attributes for 'count' vertices. 6534a49301eSmrg */ 65401e04c3fSmrgstatic void PIPE_CDECL 65501e04c3fSmrggeneric_run_elts(struct translate *translate, 65601e04c3fSmrg const unsigned *elts, 65701e04c3fSmrg unsigned count, 65801e04c3fSmrg unsigned start_instance, 65901e04c3fSmrg unsigned instance_id, 66001e04c3fSmrg void *output_buffer) 6614a49301eSmrg{ 6624a49301eSmrg struct translate_generic *tg = translate_generic(translate); 6634a49301eSmrg char *vert = output_buffer; 6644a49301eSmrg unsigned i; 6654a49301eSmrg 6664a49301eSmrg for (i = 0; i < count; i++) { 667af69d88dSmrg generic_run_one(tg, *elts++, start_instance, instance_id, vert); 6683464ebd5Sriastradh vert += tg->translate.key.output_stride; 6693464ebd5Sriastradh } 6703464ebd5Sriastradh} 6714a49301eSmrg 67201e04c3fSmrgstatic void PIPE_CDECL 67301e04c3fSmrggeneric_run_elts16(struct translate *translate, 67401e04c3fSmrg const uint16_t *elts, 67501e04c3fSmrg unsigned count, 67601e04c3fSmrg unsigned start_instance, 67701e04c3fSmrg unsigned instance_id, 67801e04c3fSmrg void *output_buffer) 6793464ebd5Sriastradh{ 6803464ebd5Sriastradh struct translate_generic *tg = translate_generic(translate); 6813464ebd5Sriastradh char *vert = output_buffer; 6823464ebd5Sriastradh unsigned i; 6834a49301eSmrg 6843464ebd5Sriastradh for (i = 0; i < count; i++) { 685af69d88dSmrg generic_run_one(tg, *elts++, start_instance, instance_id, vert); 6864a49301eSmrg vert += tg->translate.key.output_stride; 6874a49301eSmrg } 6884a49301eSmrg} 6894a49301eSmrg 69001e04c3fSmrgstatic void PIPE_CDECL 69101e04c3fSmrggeneric_run_elts8(struct translate *translate, 69201e04c3fSmrg const uint8_t *elts, 69301e04c3fSmrg unsigned count, 69401e04c3fSmrg unsigned start_instance, 69501e04c3fSmrg unsigned instance_id, 69601e04c3fSmrg void *output_buffer) 6973464ebd5Sriastradh{ 6983464ebd5Sriastradh struct translate_generic *tg = translate_generic(translate); 6993464ebd5Sriastradh char *vert = output_buffer; 7003464ebd5Sriastradh unsigned i; 7014a49301eSmrg 7023464ebd5Sriastradh for (i = 0; i < count; i++) { 703af69d88dSmrg generic_run_one(tg, *elts++, start_instance, instance_id, vert); 7043464ebd5Sriastradh vert += tg->translate.key.output_stride; 7053464ebd5Sriastradh } 7063464ebd5Sriastradh} 7074a49301eSmrg 70801e04c3fSmrgstatic void PIPE_CDECL 70901e04c3fSmrggeneric_run(struct translate *translate, 71001e04c3fSmrg unsigned start, 71101e04c3fSmrg unsigned count, 71201e04c3fSmrg unsigned start_instance, 71301e04c3fSmrg unsigned instance_id, 71401e04c3fSmrg void *output_buffer) 7154a49301eSmrg{ 7164a49301eSmrg struct translate_generic *tg = translate_generic(translate); 7174a49301eSmrg char *vert = output_buffer; 7184a49301eSmrg unsigned i; 7194a49301eSmrg 7204a49301eSmrg for (i = 0; i < count; i++) { 721af69d88dSmrg generic_run_one(tg, start + i, start_instance, instance_id, vert); 7224a49301eSmrg vert += tg->translate.key.output_stride; 7234a49301eSmrg } 7244a49301eSmrg} 7254a49301eSmrg 7264a49301eSmrg 72701e04c3fSmrg 72801e04c3fSmrgstatic void 72901e04c3fSmrggeneric_set_buffer(struct translate *translate, 73001e04c3fSmrg unsigned buf, 73101e04c3fSmrg const void *ptr, 73201e04c3fSmrg unsigned stride, 73301e04c3fSmrg unsigned max_index) 7344a49301eSmrg{ 7354a49301eSmrg struct translate_generic *tg = translate_generic(translate); 7364a49301eSmrg unsigned i; 7374a49301eSmrg 7384a49301eSmrg for (i = 0; i < tg->nr_attrib; i++) { 7394a49301eSmrg if (tg->attrib[i].buffer == buf) { 74001e04c3fSmrg tg->attrib[i].input_ptr = ((const uint8_t *)ptr + 74101e04c3fSmrg tg->attrib[i].input_offset); 74201e04c3fSmrg tg->attrib[i].input_stride = stride; 7433464ebd5Sriastradh tg->attrib[i].max_index = max_index; 7444a49301eSmrg } 7454a49301eSmrg } 7464a49301eSmrg} 7474a49301eSmrg 7484a49301eSmrg 74901e04c3fSmrgstatic void 75001e04c3fSmrggeneric_release(struct translate *translate) 7514a49301eSmrg{ 7524a49301eSmrg /* Refcount? 7534a49301eSmrg */ 7544a49301eSmrg FREE(translate); 7554a49301eSmrg} 7564a49301eSmrg 757af69d88dSmrgstatic boolean 75801e04c3fSmrgis_legal_int_format_combo(const struct util_format_description *src, 75901e04c3fSmrg const struct util_format_description *dst) 760af69d88dSmrg{ 761af69d88dSmrg unsigned i; 762af69d88dSmrg unsigned nr = MIN2(src->nr_channels, dst->nr_channels); 763af69d88dSmrg 764af69d88dSmrg for (i = 0; i < nr; i++) { 765af69d88dSmrg /* The signs must match. */ 766af69d88dSmrg if (src->channel[i].type != dst->channel[i].type) { 767af69d88dSmrg return FALSE; 768af69d88dSmrg } 769af69d88dSmrg 770af69d88dSmrg /* Integers must not lose precision at any point in the pipeline. */ 771af69d88dSmrg if (src->channel[i].size > dst->channel[i].size) { 772af69d88dSmrg return FALSE; 773af69d88dSmrg } 774af69d88dSmrg } 775af69d88dSmrg return TRUE; 776af69d88dSmrg} 777af69d88dSmrg 77801e04c3fSmrgstruct translate * 77901e04c3fSmrgtranslate_generic_create(const struct translate_key *key) 7804a49301eSmrg{ 7814a49301eSmrg struct translate_generic *tg = CALLOC_STRUCT(translate_generic); 7824a49301eSmrg unsigned i; 7834a49301eSmrg 78401e04c3fSmrg if (!tg) 7854a49301eSmrg return NULL; 7864a49301eSmrg 787af69d88dSmrg assert(key->nr_elements <= TRANSLATE_MAX_ATTRIBS); 788af69d88dSmrg 7894a49301eSmrg tg->translate.key = *key; 7904a49301eSmrg tg->translate.release = generic_release; 7914a49301eSmrg tg->translate.set_buffer = generic_set_buffer; 7924a49301eSmrg tg->translate.run_elts = generic_run_elts; 7933464ebd5Sriastradh tg->translate.run_elts16 = generic_run_elts16; 7943464ebd5Sriastradh tg->translate.run_elts8 = generic_run_elts8; 7954a49301eSmrg tg->translate.run = generic_run; 7964a49301eSmrg 7974a49301eSmrg for (i = 0; i < key->nr_elements; i++) { 7983464ebd5Sriastradh const struct util_format_description *format_desc = 7993464ebd5Sriastradh util_format_description(key->element[i].input_format); 8007ec681f3Smrg const struct util_format_unpack_description *unpack = 8017ec681f3Smrg util_format_unpack_description(key->element[i].input_format); 8023464ebd5Sriastradh 8033464ebd5Sriastradh assert(format_desc); 8043464ebd5Sriastradh 805cdc920a0Smrg tg->attrib[i].type = key->element[i].type; 8064a49301eSmrg 807af69d88dSmrg if (format_desc->channel[0].pure_integer) { 808af69d88dSmrg const struct util_format_description *out_format_desc = 809af69d88dSmrg util_format_description(key->element[i].output_format); 810af69d88dSmrg 811af69d88dSmrg if (!is_legal_int_format_combo(format_desc, out_format_desc)) { 812af69d88dSmrg FREE(tg); 813af69d88dSmrg return NULL; 814af69d88dSmrg } 815af69d88dSmrg } 816af69d88dSmrg 8177ec681f3Smrg tg->attrib[i].fetch = unpack->unpack_rgba; 8184a49301eSmrg tg->attrib[i].buffer = key->element[i].input_buffer; 8194a49301eSmrg tg->attrib[i].input_offset = key->element[i].input_offset; 820cdc920a0Smrg tg->attrib[i].instance_divisor = key->element[i].instance_divisor; 8214a49301eSmrg 8224a49301eSmrg tg->attrib[i].output_offset = key->element[i].output_offset; 8234a49301eSmrg 8243464ebd5Sriastradh tg->attrib[i].copy_size = -1; 82501e04c3fSmrg if (tg->attrib[i].type == TRANSLATE_ELEMENT_INSTANCE_ID) { 82601e04c3fSmrg if (key->element[i].output_format == PIPE_FORMAT_R32_USCALED 82701e04c3fSmrg || key->element[i].output_format == PIPE_FORMAT_R32_SSCALED) 82801e04c3fSmrg tg->attrib[i].copy_size = 4; 82901e04c3fSmrg } else { 83001e04c3fSmrg if (key->element[i].input_format == key->element[i].output_format 83101e04c3fSmrg && format_desc->block.width == 1 83201e04c3fSmrg && format_desc->block.height == 1 83301e04c3fSmrg && !(format_desc->block.bits & 7)) 8343464ebd5Sriastradh tg->attrib[i].copy_size = format_desc->block.bits >> 3; 8353464ebd5Sriastradh } 8363464ebd5Sriastradh 83701e04c3fSmrg if (tg->attrib[i].copy_size < 0) 83801e04c3fSmrg tg->attrib[i].emit = get_emit_func(key->element[i].output_format); 8393464ebd5Sriastradh else 84001e04c3fSmrg tg->attrib[i].emit = NULL; 8414a49301eSmrg } 8424a49301eSmrg 8434a49301eSmrg tg->nr_attrib = key->nr_elements; 8444a49301eSmrg 8454a49301eSmrg return &tg->translate; 8464a49301eSmrg} 8473464ebd5Sriastradh 84801e04c3fSmrgboolean 84901e04c3fSmrgtranslate_generic_is_output_format_supported(enum pipe_format format) 8503464ebd5Sriastradh{ 85101e04c3fSmrg switch(format) { 8523464ebd5Sriastradh case PIPE_FORMAT_R64G64B64A64_FLOAT: return TRUE; 8533464ebd5Sriastradh case PIPE_FORMAT_R64G64B64_FLOAT: return TRUE; 8543464ebd5Sriastradh case PIPE_FORMAT_R64G64_FLOAT: return TRUE; 8553464ebd5Sriastradh case PIPE_FORMAT_R64_FLOAT: return TRUE; 8563464ebd5Sriastradh 8573464ebd5Sriastradh case PIPE_FORMAT_R32G32B32A32_FLOAT: return TRUE; 8583464ebd5Sriastradh case PIPE_FORMAT_R32G32B32_FLOAT: return TRUE; 8593464ebd5Sriastradh case PIPE_FORMAT_R32G32_FLOAT: return TRUE; 8603464ebd5Sriastradh case PIPE_FORMAT_R32_FLOAT: return TRUE; 8613464ebd5Sriastradh 862af69d88dSmrg case PIPE_FORMAT_R16G16B16A16_FLOAT: return TRUE; 863af69d88dSmrg case PIPE_FORMAT_R16G16B16_FLOAT: return TRUE; 864af69d88dSmrg case PIPE_FORMAT_R16G16_FLOAT: return TRUE; 865af69d88dSmrg case PIPE_FORMAT_R16_FLOAT: return TRUE; 866af69d88dSmrg 8673464ebd5Sriastradh case PIPE_FORMAT_R32G32B32A32_USCALED: return TRUE; 8683464ebd5Sriastradh case PIPE_FORMAT_R32G32B32_USCALED: return TRUE; 8693464ebd5Sriastradh case PIPE_FORMAT_R32G32_USCALED: return TRUE; 8703464ebd5Sriastradh case PIPE_FORMAT_R32_USCALED: return TRUE; 8713464ebd5Sriastradh 8723464ebd5Sriastradh case PIPE_FORMAT_R32G32B32A32_SSCALED: return TRUE; 8733464ebd5Sriastradh case PIPE_FORMAT_R32G32B32_SSCALED: return TRUE; 8743464ebd5Sriastradh case PIPE_FORMAT_R32G32_SSCALED: return TRUE; 8753464ebd5Sriastradh case PIPE_FORMAT_R32_SSCALED: return TRUE; 8763464ebd5Sriastradh 8773464ebd5Sriastradh case PIPE_FORMAT_R32G32B32A32_UNORM: return TRUE; 8783464ebd5Sriastradh case PIPE_FORMAT_R32G32B32_UNORM: return TRUE; 8793464ebd5Sriastradh case PIPE_FORMAT_R32G32_UNORM: return TRUE; 8803464ebd5Sriastradh case PIPE_FORMAT_R32_UNORM: return TRUE; 8813464ebd5Sriastradh 8823464ebd5Sriastradh case PIPE_FORMAT_R32G32B32A32_SNORM: return TRUE; 8833464ebd5Sriastradh case PIPE_FORMAT_R32G32B32_SNORM: return TRUE; 8843464ebd5Sriastradh case PIPE_FORMAT_R32G32_SNORM: return TRUE; 8853464ebd5Sriastradh case PIPE_FORMAT_R32_SNORM: return TRUE; 8863464ebd5Sriastradh 8873464ebd5Sriastradh case PIPE_FORMAT_R16G16B16A16_USCALED: return TRUE; 8883464ebd5Sriastradh case PIPE_FORMAT_R16G16B16_USCALED: return TRUE; 8893464ebd5Sriastradh case PIPE_FORMAT_R16G16_USCALED: return TRUE; 8903464ebd5Sriastradh case PIPE_FORMAT_R16_USCALED: return TRUE; 8913464ebd5Sriastradh 8923464ebd5Sriastradh case PIPE_FORMAT_R16G16B16A16_SSCALED: return TRUE; 8933464ebd5Sriastradh case PIPE_FORMAT_R16G16B16_SSCALED: return TRUE; 8943464ebd5Sriastradh case PIPE_FORMAT_R16G16_SSCALED: return TRUE; 8953464ebd5Sriastradh case PIPE_FORMAT_R16_SSCALED: return TRUE; 8963464ebd5Sriastradh 8973464ebd5Sriastradh case PIPE_FORMAT_R16G16B16A16_UNORM: return TRUE; 8983464ebd5Sriastradh case PIPE_FORMAT_R16G16B16_UNORM: return TRUE; 8993464ebd5Sriastradh case PIPE_FORMAT_R16G16_UNORM: return TRUE; 9003464ebd5Sriastradh case PIPE_FORMAT_R16_UNORM: return TRUE; 9013464ebd5Sriastradh 9023464ebd5Sriastradh case PIPE_FORMAT_R16G16B16A16_SNORM: return TRUE; 9033464ebd5Sriastradh case PIPE_FORMAT_R16G16B16_SNORM: return TRUE; 9043464ebd5Sriastradh case PIPE_FORMAT_R16G16_SNORM: return TRUE; 9053464ebd5Sriastradh case PIPE_FORMAT_R16_SNORM: return TRUE; 9063464ebd5Sriastradh 9073464ebd5Sriastradh case PIPE_FORMAT_R8G8B8A8_USCALED: return TRUE; 9083464ebd5Sriastradh case PIPE_FORMAT_R8G8B8_USCALED: return TRUE; 9093464ebd5Sriastradh case PIPE_FORMAT_R8G8_USCALED: return TRUE; 9103464ebd5Sriastradh case PIPE_FORMAT_R8_USCALED: return TRUE; 9113464ebd5Sriastradh 9123464ebd5Sriastradh case PIPE_FORMAT_R8G8B8A8_SSCALED: return TRUE; 9133464ebd5Sriastradh case PIPE_FORMAT_R8G8B8_SSCALED: return TRUE; 9143464ebd5Sriastradh case PIPE_FORMAT_R8G8_SSCALED: return TRUE; 9153464ebd5Sriastradh case PIPE_FORMAT_R8_SSCALED: return TRUE; 9163464ebd5Sriastradh 9173464ebd5Sriastradh case PIPE_FORMAT_R8G8B8A8_UNORM: return TRUE; 9183464ebd5Sriastradh case PIPE_FORMAT_R8G8B8_UNORM: return TRUE; 9193464ebd5Sriastradh case PIPE_FORMAT_R8G8_UNORM: return TRUE; 9203464ebd5Sriastradh case PIPE_FORMAT_R8_UNORM: return TRUE; 9213464ebd5Sriastradh 9223464ebd5Sriastradh case PIPE_FORMAT_R8G8B8A8_SNORM: return TRUE; 9233464ebd5Sriastradh case PIPE_FORMAT_R8G8B8_SNORM: return TRUE; 9243464ebd5Sriastradh case PIPE_FORMAT_R8G8_SNORM: return TRUE; 9253464ebd5Sriastradh case PIPE_FORMAT_R8_SNORM: return TRUE; 9263464ebd5Sriastradh 9273464ebd5Sriastradh case PIPE_FORMAT_A8R8G8B8_UNORM: return TRUE; 9283464ebd5Sriastradh case PIPE_FORMAT_B8G8R8A8_UNORM: return TRUE; 929af69d88dSmrg 930af69d88dSmrg case PIPE_FORMAT_R32G32B32A32_UINT: return TRUE; 931af69d88dSmrg case PIPE_FORMAT_R32G32B32_UINT: return TRUE; 932af69d88dSmrg case PIPE_FORMAT_R32G32_UINT: return TRUE; 933af69d88dSmrg case PIPE_FORMAT_R32_UINT: return TRUE; 934af69d88dSmrg 935af69d88dSmrg case PIPE_FORMAT_R16G16B16A16_UINT: return TRUE; 936af69d88dSmrg case PIPE_FORMAT_R16G16B16_UINT: return TRUE; 937af69d88dSmrg case PIPE_FORMAT_R16G16_UINT: return TRUE; 938af69d88dSmrg case PIPE_FORMAT_R16_UINT: return TRUE; 939af69d88dSmrg 940af69d88dSmrg case PIPE_FORMAT_R8G8B8A8_UINT: return TRUE; 941af69d88dSmrg case PIPE_FORMAT_R8G8B8_UINT: return TRUE; 942af69d88dSmrg case PIPE_FORMAT_R8G8_UINT: return TRUE; 943af69d88dSmrg case PIPE_FORMAT_R8_UINT: return TRUE; 944af69d88dSmrg 945af69d88dSmrg case PIPE_FORMAT_R32G32B32A32_SINT: return TRUE; 946af69d88dSmrg case PIPE_FORMAT_R32G32B32_SINT: return TRUE; 947af69d88dSmrg case PIPE_FORMAT_R32G32_SINT: return TRUE; 948af69d88dSmrg case PIPE_FORMAT_R32_SINT: return TRUE; 949af69d88dSmrg 950af69d88dSmrg case PIPE_FORMAT_R16G16B16A16_SINT: return TRUE; 951af69d88dSmrg case PIPE_FORMAT_R16G16B16_SINT: return TRUE; 952af69d88dSmrg case PIPE_FORMAT_R16G16_SINT: return TRUE; 953af69d88dSmrg case PIPE_FORMAT_R16_SINT: return TRUE; 954af69d88dSmrg 955af69d88dSmrg case PIPE_FORMAT_R8G8B8A8_SINT: return TRUE; 956af69d88dSmrg case PIPE_FORMAT_R8G8B8_SINT: return TRUE; 957af69d88dSmrg case PIPE_FORMAT_R8G8_SINT: return TRUE; 958af69d88dSmrg case PIPE_FORMAT_R8_SINT: return TRUE; 959af69d88dSmrg 960af69d88dSmrg case PIPE_FORMAT_B10G10R10A2_UNORM: return TRUE; 961af69d88dSmrg case PIPE_FORMAT_B10G10R10A2_USCALED: return TRUE; 962af69d88dSmrg case PIPE_FORMAT_B10G10R10A2_SNORM: return TRUE; 963af69d88dSmrg case PIPE_FORMAT_B10G10R10A2_SSCALED: return TRUE; 964af69d88dSmrg 965af69d88dSmrg case PIPE_FORMAT_R10G10B10A2_UNORM: return TRUE; 966af69d88dSmrg case PIPE_FORMAT_R10G10B10A2_USCALED: return TRUE; 967af69d88dSmrg case PIPE_FORMAT_R10G10B10A2_SNORM: return TRUE; 968af69d88dSmrg case PIPE_FORMAT_R10G10B10A2_SSCALED: return TRUE; 969af69d88dSmrg 9703464ebd5Sriastradh default: return FALSE; 9713464ebd5Sriastradh } 9723464ebd5Sriastradh} 973