1848b8605Smrg/************************************************************************** 2b8e80941Smrg * 3848b8605Smrg * Copyright 2007 VMware, Inc. 4848b8605Smrg * All Rights Reserved. 5b8e80941Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the 8848b8605Smrg * "Software"), to deal in the Software without restriction, including 9848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish, 10848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to 11848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to 12848b8605Smrg * the following conditions: 13b8e80941Smrg * 14848b8605Smrg * The above copyright notice and this permission notice (including the 15848b8605Smrg * next paragraph) shall be included in all copies or substantial portions 16848b8605Smrg * of the Software. 17b8e80941Smrg * 18848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20848b8605Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21848b8605Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22848b8605Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23848b8605Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24848b8605Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25b8e80941Smrg * 26848b8605Smrg **************************************************************************/ 27848b8605Smrg 28848b8605Smrg /* 29848b8605Smrg * Authors: 30848b8605Smrg * Keith Whitwell <keithw@vmware.com> 31848b8605Smrg */ 32848b8605Smrg 33848b8605Smrg#include "util/u_memory.h" 34848b8605Smrg#include "util/u_format.h" 35848b8605Smrg#include "util/u_half.h" 36848b8605Smrg#include "util/u_math.h" 37848b8605Smrg#include "pipe/p_state.h" 38848b8605Smrg#include "translate.h" 39848b8605Smrg 40848b8605Smrg 41848b8605Smrg#define DRAW_DBG 0 42848b8605Smrg 43848b8605Smrgtypedef void (*fetch_func)(void *dst, 44848b8605Smrg const uint8_t *src, 45848b8605Smrg unsigned i, unsigned j); 46848b8605Smrgtypedef void (*emit_func)(const void *attrib, void *ptr); 47848b8605Smrg 48848b8605Smrg 49848b8605Smrg 50848b8605Smrgstruct translate_generic { 51848b8605Smrg struct translate translate; 52848b8605Smrg 53848b8605Smrg struct { 54848b8605Smrg enum translate_element_type type; 55848b8605Smrg 56848b8605Smrg fetch_func fetch; 57848b8605Smrg unsigned buffer; 58848b8605Smrg unsigned input_offset; 59848b8605Smrg unsigned instance_divisor; 60848b8605Smrg 61848b8605Smrg emit_func emit; 62848b8605Smrg unsigned output_offset; 63b8e80941Smrg 64848b8605Smrg const uint8_t *input_ptr; 65848b8605Smrg unsigned input_stride; 66848b8605Smrg unsigned max_index; 67848b8605Smrg 68b8e80941Smrg /* this value is set to -1 if this is a normal element with 69b8e80941Smrg * output_format != input_format: in this case, u_format is used 70b8e80941Smrg * to do a full conversion 71848b8605Smrg * 72b8e80941Smrg * this value is set to the format size in bytes if 73b8e80941Smrg * output_format == input_format or for 32-bit instance ids: 74848b8605Smrg * in this case, memcpy is used to copy this amount of bytes 75848b8605Smrg */ 76848b8605Smrg int copy_size; 77848b8605Smrg 78848b8605Smrg } attrib[TRANSLATE_MAX_ATTRIBS]; 79848b8605Smrg 80848b8605Smrg unsigned nr_attrib; 81848b8605Smrg}; 82848b8605Smrg 83848b8605Smrg 84b8e80941Smrgstatic struct translate_generic * 85b8e80941Smrgtranslate_generic(struct translate *translate) 86848b8605Smrg{ 87848b8605Smrg return (struct translate_generic *)translate; 88848b8605Smrg} 89848b8605Smrg 90b8e80941Smrg 91848b8605Smrg/** 92848b8605Smrg * Fetch a dword[4] vertex attribute from memory, doing format/type 93848b8605Smrg * conversion as needed. 94848b8605Smrg * 95848b8605Smrg * This is probably needed/dupliocated elsewhere, eg format 96848b8605Smrg * conversion, texture sampling etc. 97848b8605Smrg */ 98b8e80941Smrg#define ATTRIB(NAME, SZ, SRCTYPE, DSTTYPE, TO) \ 99848b8605Smrgstatic void \ 100848b8605Smrgemit_##NAME(const void *attrib, void *ptr) \ 101848b8605Smrg{ \ 102848b8605Smrg unsigned i; \ 103848b8605Smrg SRCTYPE *in = (SRCTYPE *)attrib; \ 104848b8605Smrg DSTTYPE *out = (DSTTYPE *)ptr; \ 105848b8605Smrg \ 106848b8605Smrg for (i = 0; i < SZ; i++) { \ 107848b8605Smrg out[i] = TO(in[i]); \ 108848b8605Smrg } \ 109848b8605Smrg} 110848b8605Smrg 111848b8605Smrg 112848b8605Smrg#define TO_64_FLOAT(x) ((double) x) 113848b8605Smrg#define TO_32_FLOAT(x) (x) 114848b8605Smrg#define TO_16_FLOAT(x) util_float_to_half(x) 115848b8605Smrg 116848b8605Smrg#define TO_8_USCALED(x) ((unsigned char) x) 117848b8605Smrg#define TO_16_USCALED(x) ((unsigned short) x) 118848b8605Smrg#define TO_32_USCALED(x) ((unsigned int) x) 119848b8605Smrg 120848b8605Smrg#define TO_8_SSCALED(x) ((char) x) 121848b8605Smrg#define TO_16_SSCALED(x) ((short) x) 122848b8605Smrg#define TO_32_SSCALED(x) ((int) x) 123848b8605Smrg 124848b8605Smrg#define TO_8_UNORM(x) ((unsigned char) (x * 255.0f)) 125848b8605Smrg#define TO_16_UNORM(x) ((unsigned short) (x * 65535.0f)) 126848b8605Smrg#define TO_32_UNORM(x) ((unsigned int) (x * 4294967295.0f)) 127848b8605Smrg 128848b8605Smrg#define TO_8_SNORM(x) ((char) (x * 127.0f)) 129848b8605Smrg#define TO_16_SNORM(x) ((short) (x * 32767.0f)) 130848b8605Smrg#define TO_32_SNORM(x) ((int) (x * 2147483647.0f)) 131848b8605Smrg 132848b8605Smrg#define TO_32_FIXED(x) ((int) (x * 65536.0f)) 133848b8605Smrg 134848b8605Smrg#define TO_INT(x) (x) 135848b8605Smrg 136848b8605Smrg 137b8e80941SmrgATTRIB(R64G64B64A64_FLOAT, 4, float, double, TO_64_FLOAT) 138b8e80941SmrgATTRIB(R64G64B64_FLOAT, 3, float, double, TO_64_FLOAT) 139b8e80941SmrgATTRIB(R64G64_FLOAT, 2, float, double, TO_64_FLOAT) 140b8e80941SmrgATTRIB(R64_FLOAT, 1, float, double, TO_64_FLOAT) 141b8e80941Smrg 142b8e80941SmrgATTRIB(R32G32B32A32_FLOAT, 4, float, float, TO_32_FLOAT) 143b8e80941SmrgATTRIB(R32G32B32_FLOAT, 3, float, float, TO_32_FLOAT) 144b8e80941SmrgATTRIB(R32G32_FLOAT, 2, float, float, TO_32_FLOAT) 145b8e80941SmrgATTRIB(R32_FLOAT, 1, float, float, TO_32_FLOAT) 146b8e80941Smrg 147b8e80941SmrgATTRIB(R16G16B16A16_FLOAT, 4, float, ushort, TO_16_FLOAT) 148b8e80941SmrgATTRIB(R16G16B16_FLOAT, 3, float, ushort, TO_16_FLOAT) 149b8e80941SmrgATTRIB(R16G16_FLOAT, 2, float, ushort, TO_16_FLOAT) 150b8e80941SmrgATTRIB(R16_FLOAT, 1, float, ushort, TO_16_FLOAT) 151b8e80941Smrg 152b8e80941SmrgATTRIB(R32G32B32A32_USCALED, 4, float, unsigned, TO_32_USCALED) 153b8e80941SmrgATTRIB(R32G32B32_USCALED, 3, float, unsigned, TO_32_USCALED) 154b8e80941SmrgATTRIB(R32G32_USCALED, 2, float, unsigned, TO_32_USCALED) 155b8e80941SmrgATTRIB(R32_USCALED, 1, float, unsigned, TO_32_USCALED) 156b8e80941Smrg 157b8e80941SmrgATTRIB(R32G32B32A32_SSCALED, 4, float, int, TO_32_SSCALED) 158b8e80941SmrgATTRIB(R32G32B32_SSCALED, 3, float, int, TO_32_SSCALED) 159b8e80941SmrgATTRIB(R32G32_SSCALED, 2, float, int, TO_32_SSCALED) 160b8e80941SmrgATTRIB(R32_SSCALED, 1, float, int, TO_32_SSCALED) 161b8e80941Smrg 162b8e80941SmrgATTRIB(R32G32B32A32_UNORM, 4, float, unsigned, TO_32_UNORM) 163b8e80941SmrgATTRIB(R32G32B32_UNORM, 3, float, unsigned, TO_32_UNORM) 164b8e80941SmrgATTRIB(R32G32_UNORM, 2, float, unsigned, TO_32_UNORM) 165b8e80941SmrgATTRIB(R32_UNORM, 1, float, unsigned, TO_32_UNORM) 166b8e80941Smrg 167b8e80941SmrgATTRIB(R32G32B32A32_SNORM, 4, float, int, TO_32_SNORM) 168b8e80941SmrgATTRIB(R32G32B32_SNORM, 3, float, int, TO_32_SNORM) 169b8e80941SmrgATTRIB(R32G32_SNORM, 2, float, int, TO_32_SNORM) 170b8e80941SmrgATTRIB(R32_SNORM, 1, float, int, TO_32_SNORM) 171b8e80941Smrg 172b8e80941SmrgATTRIB(R16G16B16A16_USCALED, 4, float, ushort, TO_16_USCALED) 173b8e80941SmrgATTRIB(R16G16B16_USCALED, 3, float, ushort, TO_16_USCALED) 174b8e80941SmrgATTRIB(R16G16_USCALED, 2, float, ushort, TO_16_USCALED) 175b8e80941SmrgATTRIB(R16_USCALED, 1, float, ushort, TO_16_USCALED) 176b8e80941Smrg 177b8e80941SmrgATTRIB(R16G16B16A16_SSCALED, 4, float, short, TO_16_SSCALED) 178b8e80941SmrgATTRIB(R16G16B16_SSCALED, 3, float, short, TO_16_SSCALED) 179b8e80941SmrgATTRIB(R16G16_SSCALED, 2, float, short, TO_16_SSCALED) 180b8e80941SmrgATTRIB(R16_SSCALED, 1, float, short, TO_16_SSCALED) 181b8e80941Smrg 182b8e80941SmrgATTRIB(R16G16B16A16_UNORM, 4, float, ushort, TO_16_UNORM) 183b8e80941SmrgATTRIB(R16G16B16_UNORM, 3, float, ushort, TO_16_UNORM) 184b8e80941SmrgATTRIB(R16G16_UNORM, 2, float, ushort, TO_16_UNORM) 185b8e80941SmrgATTRIB(R16_UNORM, 1, float, ushort, TO_16_UNORM) 186b8e80941Smrg 187b8e80941SmrgATTRIB(R16G16B16A16_SNORM, 4, float, short, TO_16_SNORM) 188b8e80941SmrgATTRIB(R16G16B16_SNORM, 3, float, short, TO_16_SNORM) 189b8e80941SmrgATTRIB(R16G16_SNORM, 2, float, short, TO_16_SNORM) 190b8e80941SmrgATTRIB(R16_SNORM, 1, float, short, TO_16_SNORM) 191b8e80941Smrg 192b8e80941SmrgATTRIB(R8G8B8A8_USCALED, 4, float, ubyte, TO_8_USCALED) 193b8e80941SmrgATTRIB(R8G8B8_USCALED, 3, float, ubyte, TO_8_USCALED) 194b8e80941SmrgATTRIB(R8G8_USCALED, 2, float, ubyte, TO_8_USCALED) 195b8e80941SmrgATTRIB(R8_USCALED, 1, float, ubyte, TO_8_USCALED) 196b8e80941Smrg 197b8e80941SmrgATTRIB(R8G8B8A8_SSCALED, 4, float, char, TO_8_SSCALED) 198b8e80941SmrgATTRIB(R8G8B8_SSCALED, 3, float, char, TO_8_SSCALED) 199b8e80941SmrgATTRIB(R8G8_SSCALED, 2, float, char, TO_8_SSCALED) 200b8e80941SmrgATTRIB(R8_SSCALED, 1, float, char, TO_8_SSCALED) 201b8e80941Smrg 202b8e80941SmrgATTRIB(R8G8B8A8_UNORM, 4, float, ubyte, TO_8_UNORM) 203b8e80941SmrgATTRIB(R8G8B8_UNORM, 3, float, ubyte, TO_8_UNORM) 204b8e80941SmrgATTRIB(R8G8_UNORM, 2, float, ubyte, TO_8_UNORM) 205b8e80941SmrgATTRIB(R8_UNORM, 1, float, ubyte, TO_8_UNORM) 206b8e80941Smrg 207b8e80941SmrgATTRIB(R8G8B8A8_SNORM, 4, float, char, TO_8_SNORM) 208b8e80941SmrgATTRIB(R8G8B8_SNORM, 3, float, char, TO_8_SNORM) 209b8e80941SmrgATTRIB(R8G8_SNORM, 2, float, char, TO_8_SNORM) 210b8e80941SmrgATTRIB(R8_SNORM, 1, float, char, TO_8_SNORM) 211b8e80941Smrg 212b8e80941SmrgATTRIB(R32G32B32A32_UINT, 4, uint32_t, unsigned, TO_INT) 213b8e80941SmrgATTRIB(R32G32B32_UINT, 3, uint32_t, unsigned, TO_INT) 214b8e80941SmrgATTRIB(R32G32_UINT, 2, uint32_t, unsigned, TO_INT) 215b8e80941SmrgATTRIB(R32_UINT, 1, uint32_t, unsigned, TO_INT) 216b8e80941Smrg 217b8e80941SmrgATTRIB(R16G16B16A16_UINT, 4, uint32_t, ushort, TO_INT) 218b8e80941SmrgATTRIB(R16G16B16_UINT, 3, uint32_t, ushort, TO_INT) 219b8e80941SmrgATTRIB(R16G16_UINT, 2, uint32_t, ushort, TO_INT) 220b8e80941SmrgATTRIB(R16_UINT, 1, uint32_t, ushort, TO_INT) 221b8e80941Smrg 222b8e80941SmrgATTRIB(R8G8B8A8_UINT, 4, uint32_t, ubyte, TO_INT) 223b8e80941SmrgATTRIB(R8G8B8_UINT, 3, uint32_t, ubyte, TO_INT) 224b8e80941SmrgATTRIB(R8G8_UINT, 2, uint32_t, ubyte, TO_INT) 225b8e80941SmrgATTRIB(R8_UINT, 1, uint32_t, ubyte, TO_INT) 226b8e80941Smrg 227b8e80941SmrgATTRIB(R32G32B32A32_SINT, 4, int32_t, int, TO_INT) 228b8e80941SmrgATTRIB(R32G32B32_SINT, 3, int32_t, int, TO_INT) 229b8e80941SmrgATTRIB(R32G32_SINT, 2, int32_t, int, TO_INT) 230b8e80941SmrgATTRIB(R32_SINT, 1, int32_t, int, TO_INT) 231b8e80941Smrg 232b8e80941SmrgATTRIB(R16G16B16A16_SINT, 4, int32_t, short, TO_INT) 233b8e80941SmrgATTRIB(R16G16B16_SINT, 3, int32_t, short, TO_INT) 234b8e80941SmrgATTRIB(R16G16_SINT, 2, int32_t, short, TO_INT) 235b8e80941SmrgATTRIB(R16_SINT, 1, int32_t, short, TO_INT) 236b8e80941Smrg 237b8e80941SmrgATTRIB(R8G8B8A8_SINT, 4, int32_t, char, TO_INT) 238b8e80941SmrgATTRIB(R8G8B8_SINT, 3, int32_t, char, TO_INT) 239b8e80941SmrgATTRIB(R8G8_SINT, 2, int32_t, char, TO_INT) 240b8e80941SmrgATTRIB(R8_SINT, 1, int32_t, char, TO_INT) 241848b8605Smrg 242848b8605Smrgstatic void 243b8e80941Smrgemit_A8R8G8B8_UNORM(const void *attrib, void *ptr) 244848b8605Smrg{ 245848b8605Smrg float *in = (float *)attrib; 246848b8605Smrg ubyte *out = (ubyte *)ptr; 247848b8605Smrg out[0] = TO_8_UNORM(in[3]); 248848b8605Smrg out[1] = TO_8_UNORM(in[0]); 249848b8605Smrg out[2] = TO_8_UNORM(in[1]); 250848b8605Smrg out[3] = TO_8_UNORM(in[2]); 251848b8605Smrg} 252848b8605Smrg 253848b8605Smrgstatic void 254b8e80941Smrgemit_B8G8R8A8_UNORM(const void *attrib, void *ptr) 255848b8605Smrg{ 256848b8605Smrg float *in = (float *)attrib; 257848b8605Smrg ubyte *out = (ubyte *)ptr; 258848b8605Smrg out[2] = TO_8_UNORM(in[0]); 259848b8605Smrg out[1] = TO_8_UNORM(in[1]); 260848b8605Smrg out[0] = TO_8_UNORM(in[2]); 261848b8605Smrg out[3] = TO_8_UNORM(in[3]); 262848b8605Smrg} 263848b8605Smrg 264848b8605Smrgstatic void 265b8e80941Smrgemit_B10G10R10A2_UNORM(const void *attrib, void *ptr) 266848b8605Smrg{ 267848b8605Smrg float *src = (float *)ptr; 268848b8605Smrg uint32_t value = 0; 269848b8605Smrg value |= ((uint32_t)(CLAMP(src[2], 0, 1) * 0x3ff)) & 0x3ff; 270848b8605Smrg value |= (((uint32_t)(CLAMP(src[1], 0, 1) * 0x3ff)) & 0x3ff) << 10; 271848b8605Smrg value |= (((uint32_t)(CLAMP(src[0], 0, 1) * 0x3ff)) & 0x3ff) << 20; 272848b8605Smrg value |= ((uint32_t)(CLAMP(src[3], 0, 1) * 0x3)) << 30; 273b8e80941Smrg *(uint32_t *)attrib = util_le32_to_cpu(value); 274848b8605Smrg} 275848b8605Smrg 276848b8605Smrgstatic void 277b8e80941Smrgemit_B10G10R10A2_USCALED(const void *attrib, void *ptr) 278848b8605Smrg{ 279848b8605Smrg float *src = (float *)ptr; 280848b8605Smrg uint32_t value = 0; 281848b8605Smrg value |= ((uint32_t)CLAMP(src[2], 0, 1023)) & 0x3ff; 282848b8605Smrg value |= (((uint32_t)CLAMP(src[1], 0, 1023)) & 0x3ff) << 10; 283848b8605Smrg value |= (((uint32_t)CLAMP(src[0], 0, 1023)) & 0x3ff) << 20; 284848b8605Smrg value |= ((uint32_t)CLAMP(src[3], 0, 3)) << 30; 285b8e80941Smrg *(uint32_t *)attrib = util_le32_to_cpu(value); 286848b8605Smrg} 287848b8605Smrg 288848b8605Smrgstatic void 289b8e80941Smrgemit_B10G10R10A2_SNORM(const void *attrib, void *ptr) 290848b8605Smrg{ 291848b8605Smrg float *src = (float *)ptr; 292848b8605Smrg uint32_t value = 0; 293848b8605Smrg value |= (uint32_t)(((uint32_t)(CLAMP(src[2], -1, 1) * 0x1ff)) & 0x3ff) ; 294848b8605Smrg value |= (uint32_t)((((uint32_t)(CLAMP(src[1], -1, 1) * 0x1ff)) & 0x3ff) << 10) ; 295848b8605Smrg value |= (uint32_t)((((uint32_t)(CLAMP(src[0], -1, 1) * 0x1ff)) & 0x3ff) << 20) ; 296848b8605Smrg value |= (uint32_t)(((uint32_t)(CLAMP(src[3], -1, 1) * 0x1)) << 30) ; 297b8e80941Smrg *(uint32_t *)attrib = util_le32_to_cpu(value); 298848b8605Smrg} 299848b8605Smrg 300848b8605Smrgstatic void 301b8e80941Smrgemit_B10G10R10A2_SSCALED(const void *attrib, void *ptr) 302848b8605Smrg{ 303848b8605Smrg float *src = (float *)ptr; 304848b8605Smrg uint32_t value = 0; 305848b8605Smrg value |= (uint32_t)(((uint32_t)CLAMP(src[2], -512, 511)) & 0x3ff) ; 306848b8605Smrg value |= (uint32_t)((((uint32_t)CLAMP(src[1], -512, 511)) & 0x3ff) << 10) ; 307848b8605Smrg value |= (uint32_t)((((uint32_t)CLAMP(src[0], -512, 511)) & 0x3ff) << 20) ; 308848b8605Smrg value |= (uint32_t)(((uint32_t)CLAMP(src[3], -2, 1)) << 30) ; 309b8e80941Smrg *(uint32_t *)attrib = util_le32_to_cpu(value); 310848b8605Smrg} 311848b8605Smrg 312848b8605Smrgstatic void 313b8e80941Smrgemit_R10G10B10A2_UNORM(const void *attrib, void *ptr) 314848b8605Smrg{ 315848b8605Smrg float *src = (float *)ptr; 316848b8605Smrg uint32_t value = 0; 317848b8605Smrg value |= ((uint32_t)(CLAMP(src[0], 0, 1) * 0x3ff)) & 0x3ff; 318848b8605Smrg value |= (((uint32_t)(CLAMP(src[1], 0, 1) * 0x3ff)) & 0x3ff) << 10; 319848b8605Smrg value |= (((uint32_t)(CLAMP(src[2], 0, 1) * 0x3ff)) & 0x3ff) << 20; 320848b8605Smrg value |= ((uint32_t)(CLAMP(src[3], 0, 1) * 0x3)) << 30; 321b8e80941Smrg *(uint32_t *)attrib = util_le32_to_cpu(value); 322848b8605Smrg} 323848b8605Smrg 324848b8605Smrgstatic void 325b8e80941Smrgemit_R10G10B10A2_USCALED(const void *attrib, void *ptr) 326848b8605Smrg{ 327848b8605Smrg float *src = (float *)ptr; 328848b8605Smrg uint32_t value = 0; 329848b8605Smrg value |= ((uint32_t)CLAMP(src[0], 0, 1023)) & 0x3ff; 330848b8605Smrg value |= (((uint32_t)CLAMP(src[1], 0, 1023)) & 0x3ff) << 10; 331848b8605Smrg value |= (((uint32_t)CLAMP(src[2], 0, 1023)) & 0x3ff) << 20; 332848b8605Smrg value |= ((uint32_t)CLAMP(src[3], 0, 3)) << 30; 333b8e80941Smrg *(uint32_t *)attrib = util_le32_to_cpu(value); 334848b8605Smrg} 335848b8605Smrg 336848b8605Smrgstatic void 337b8e80941Smrgemit_R10G10B10A2_SNORM(const void *attrib, void *ptr) 338848b8605Smrg{ 339848b8605Smrg float *src = (float *)ptr; 340848b8605Smrg uint32_t value = 0; 341848b8605Smrg value |= (uint32_t)(((uint32_t)(CLAMP(src[0], -1, 1) * 0x1ff)) & 0x3ff) ; 342848b8605Smrg value |= (uint32_t)((((uint32_t)(CLAMP(src[1], -1, 1) * 0x1ff)) & 0x3ff) << 10) ; 343848b8605Smrg value |= (uint32_t)((((uint32_t)(CLAMP(src[2], -1, 1) * 0x1ff)) & 0x3ff) << 20) ; 344848b8605Smrg value |= (uint32_t)(((uint32_t)(CLAMP(src[3], -1, 1) * 0x1)) << 30) ; 345b8e80941Smrg *(uint32_t *)attrib = util_le32_to_cpu(value); 346848b8605Smrg} 347848b8605Smrg 348848b8605Smrgstatic void 349b8e80941Smrgemit_R10G10B10A2_SSCALED(const void *attrib, void *ptr) 350848b8605Smrg{ 351848b8605Smrg float *src = (float *)ptr; 352848b8605Smrg uint32_t value = 0; 353848b8605Smrg value |= (uint32_t)(((uint32_t)CLAMP(src[0], -512, 511)) & 0x3ff) ; 354848b8605Smrg value |= (uint32_t)((((uint32_t)CLAMP(src[1], -512, 511)) & 0x3ff) << 10) ; 355848b8605Smrg value |= (uint32_t)((((uint32_t)CLAMP(src[2], -512, 511)) & 0x3ff) << 20) ; 356848b8605Smrg value |= (uint32_t)(((uint32_t)CLAMP(src[3], -2, 1)) << 30) ; 357b8e80941Smrg *(uint32_t *)attrib = util_le32_to_cpu(value); 358848b8605Smrg} 359848b8605Smrg 360b8e80941Smrgstatic void 361b8e80941Smrgemit_NULL(const void *attrib, void *ptr) 362848b8605Smrg{ 363848b8605Smrg /* do nothing is the only sensible option */ 364848b8605Smrg} 365848b8605Smrg 366b8e80941Smrgstatic emit_func 367b8e80941Smrgget_emit_func(enum pipe_format format) 368848b8605Smrg{ 369848b8605Smrg switch (format) { 370848b8605Smrg case PIPE_FORMAT_R64_FLOAT: 371848b8605Smrg return &emit_R64_FLOAT; 372848b8605Smrg case PIPE_FORMAT_R64G64_FLOAT: 373848b8605Smrg return &emit_R64G64_FLOAT; 374848b8605Smrg case PIPE_FORMAT_R64G64B64_FLOAT: 375848b8605Smrg return &emit_R64G64B64_FLOAT; 376848b8605Smrg case PIPE_FORMAT_R64G64B64A64_FLOAT: 377848b8605Smrg return &emit_R64G64B64A64_FLOAT; 378848b8605Smrg 379848b8605Smrg case PIPE_FORMAT_R32_FLOAT: 380848b8605Smrg return &emit_R32_FLOAT; 381848b8605Smrg case PIPE_FORMAT_R32G32_FLOAT: 382848b8605Smrg return &emit_R32G32_FLOAT; 383848b8605Smrg case PIPE_FORMAT_R32G32B32_FLOAT: 384848b8605Smrg return &emit_R32G32B32_FLOAT; 385848b8605Smrg case PIPE_FORMAT_R32G32B32A32_FLOAT: 386848b8605Smrg return &emit_R32G32B32A32_FLOAT; 387848b8605Smrg 388848b8605Smrg case PIPE_FORMAT_R16_FLOAT: 389848b8605Smrg return &emit_R16_FLOAT; 390848b8605Smrg case PIPE_FORMAT_R16G16_FLOAT: 391848b8605Smrg return &emit_R16G16_FLOAT; 392848b8605Smrg case PIPE_FORMAT_R16G16B16_FLOAT: 393848b8605Smrg return &emit_R16G16B16_FLOAT; 394848b8605Smrg case PIPE_FORMAT_R16G16B16A16_FLOAT: 395848b8605Smrg return &emit_R16G16B16A16_FLOAT; 396848b8605Smrg 397848b8605Smrg case PIPE_FORMAT_R32_UNORM: 398848b8605Smrg return &emit_R32_UNORM; 399848b8605Smrg case PIPE_FORMAT_R32G32_UNORM: 400848b8605Smrg return &emit_R32G32_UNORM; 401848b8605Smrg case PIPE_FORMAT_R32G32B32_UNORM: 402848b8605Smrg return &emit_R32G32B32_UNORM; 403848b8605Smrg case PIPE_FORMAT_R32G32B32A32_UNORM: 404848b8605Smrg return &emit_R32G32B32A32_UNORM; 405848b8605Smrg 406848b8605Smrg case PIPE_FORMAT_R32_USCALED: 407848b8605Smrg return &emit_R32_USCALED; 408848b8605Smrg case PIPE_FORMAT_R32G32_USCALED: 409848b8605Smrg return &emit_R32G32_USCALED; 410848b8605Smrg case PIPE_FORMAT_R32G32B32_USCALED: 411848b8605Smrg return &emit_R32G32B32_USCALED; 412848b8605Smrg case PIPE_FORMAT_R32G32B32A32_USCALED: 413848b8605Smrg return &emit_R32G32B32A32_USCALED; 414848b8605Smrg 415848b8605Smrg case PIPE_FORMAT_R32_SNORM: 416848b8605Smrg return &emit_R32_SNORM; 417848b8605Smrg case PIPE_FORMAT_R32G32_SNORM: 418848b8605Smrg return &emit_R32G32_SNORM; 419848b8605Smrg case PIPE_FORMAT_R32G32B32_SNORM: 420848b8605Smrg return &emit_R32G32B32_SNORM; 421848b8605Smrg case PIPE_FORMAT_R32G32B32A32_SNORM: 422848b8605Smrg return &emit_R32G32B32A32_SNORM; 423848b8605Smrg 424848b8605Smrg case PIPE_FORMAT_R32_SSCALED: 425848b8605Smrg return &emit_R32_SSCALED; 426848b8605Smrg case PIPE_FORMAT_R32G32_SSCALED: 427848b8605Smrg return &emit_R32G32_SSCALED; 428848b8605Smrg case PIPE_FORMAT_R32G32B32_SSCALED: 429848b8605Smrg return &emit_R32G32B32_SSCALED; 430848b8605Smrg case PIPE_FORMAT_R32G32B32A32_SSCALED: 431848b8605Smrg return &emit_R32G32B32A32_SSCALED; 432848b8605Smrg 433848b8605Smrg case PIPE_FORMAT_R16_UNORM: 434848b8605Smrg return &emit_R16_UNORM; 435848b8605Smrg case PIPE_FORMAT_R16G16_UNORM: 436848b8605Smrg return &emit_R16G16_UNORM; 437848b8605Smrg case PIPE_FORMAT_R16G16B16_UNORM: 438848b8605Smrg return &emit_R16G16B16_UNORM; 439848b8605Smrg case PIPE_FORMAT_R16G16B16A16_UNORM: 440848b8605Smrg return &emit_R16G16B16A16_UNORM; 441848b8605Smrg 442848b8605Smrg case PIPE_FORMAT_R16_USCALED: 443848b8605Smrg return &emit_R16_USCALED; 444848b8605Smrg case PIPE_FORMAT_R16G16_USCALED: 445848b8605Smrg return &emit_R16G16_USCALED; 446848b8605Smrg case PIPE_FORMAT_R16G16B16_USCALED: 447848b8605Smrg return &emit_R16G16B16_USCALED; 448848b8605Smrg case PIPE_FORMAT_R16G16B16A16_USCALED: 449848b8605Smrg return &emit_R16G16B16A16_USCALED; 450848b8605Smrg 451848b8605Smrg case PIPE_FORMAT_R16_SNORM: 452848b8605Smrg return &emit_R16_SNORM; 453848b8605Smrg case PIPE_FORMAT_R16G16_SNORM: 454848b8605Smrg return &emit_R16G16_SNORM; 455848b8605Smrg case PIPE_FORMAT_R16G16B16_SNORM: 456848b8605Smrg return &emit_R16G16B16_SNORM; 457848b8605Smrg case PIPE_FORMAT_R16G16B16A16_SNORM: 458848b8605Smrg return &emit_R16G16B16A16_SNORM; 459848b8605Smrg 460848b8605Smrg case PIPE_FORMAT_R16_SSCALED: 461848b8605Smrg return &emit_R16_SSCALED; 462848b8605Smrg case PIPE_FORMAT_R16G16_SSCALED: 463848b8605Smrg return &emit_R16G16_SSCALED; 464848b8605Smrg case PIPE_FORMAT_R16G16B16_SSCALED: 465848b8605Smrg return &emit_R16G16B16_SSCALED; 466848b8605Smrg case PIPE_FORMAT_R16G16B16A16_SSCALED: 467848b8605Smrg return &emit_R16G16B16A16_SSCALED; 468848b8605Smrg 469848b8605Smrg case PIPE_FORMAT_R8_UNORM: 470848b8605Smrg return &emit_R8_UNORM; 471848b8605Smrg case PIPE_FORMAT_R8G8_UNORM: 472848b8605Smrg return &emit_R8G8_UNORM; 473848b8605Smrg case PIPE_FORMAT_R8G8B8_UNORM: 474848b8605Smrg return &emit_R8G8B8_UNORM; 475848b8605Smrg case PIPE_FORMAT_R8G8B8A8_UNORM: 476848b8605Smrg return &emit_R8G8B8A8_UNORM; 477848b8605Smrg 478848b8605Smrg case PIPE_FORMAT_R8_USCALED: 479848b8605Smrg return &emit_R8_USCALED; 480848b8605Smrg case PIPE_FORMAT_R8G8_USCALED: 481848b8605Smrg return &emit_R8G8_USCALED; 482848b8605Smrg case PIPE_FORMAT_R8G8B8_USCALED: 483848b8605Smrg return &emit_R8G8B8_USCALED; 484848b8605Smrg case PIPE_FORMAT_R8G8B8A8_USCALED: 485848b8605Smrg return &emit_R8G8B8A8_USCALED; 486848b8605Smrg 487848b8605Smrg case PIPE_FORMAT_R8_SNORM: 488848b8605Smrg return &emit_R8_SNORM; 489848b8605Smrg case PIPE_FORMAT_R8G8_SNORM: 490848b8605Smrg return &emit_R8G8_SNORM; 491848b8605Smrg case PIPE_FORMAT_R8G8B8_SNORM: 492848b8605Smrg return &emit_R8G8B8_SNORM; 493848b8605Smrg case PIPE_FORMAT_R8G8B8A8_SNORM: 494848b8605Smrg return &emit_R8G8B8A8_SNORM; 495848b8605Smrg 496848b8605Smrg case PIPE_FORMAT_R8_SSCALED: 497848b8605Smrg return &emit_R8_SSCALED; 498848b8605Smrg case PIPE_FORMAT_R8G8_SSCALED: 499848b8605Smrg return &emit_R8G8_SSCALED; 500848b8605Smrg case PIPE_FORMAT_R8G8B8_SSCALED: 501848b8605Smrg return &emit_R8G8B8_SSCALED; 502848b8605Smrg case PIPE_FORMAT_R8G8B8A8_SSCALED: 503848b8605Smrg return &emit_R8G8B8A8_SSCALED; 504848b8605Smrg 505848b8605Smrg case PIPE_FORMAT_B8G8R8A8_UNORM: 506848b8605Smrg return &emit_B8G8R8A8_UNORM; 507848b8605Smrg 508848b8605Smrg case PIPE_FORMAT_A8R8G8B8_UNORM: 509848b8605Smrg return &emit_A8R8G8B8_UNORM; 510848b8605Smrg 511848b8605Smrg case PIPE_FORMAT_R32_UINT: 512848b8605Smrg return &emit_R32_UINT; 513848b8605Smrg case PIPE_FORMAT_R32G32_UINT: 514848b8605Smrg return &emit_R32G32_UINT; 515848b8605Smrg case PIPE_FORMAT_R32G32B32_UINT: 516848b8605Smrg return &emit_R32G32B32_UINT; 517848b8605Smrg case PIPE_FORMAT_R32G32B32A32_UINT: 518848b8605Smrg return &emit_R32G32B32A32_UINT; 519848b8605Smrg 520848b8605Smrg case PIPE_FORMAT_R16_UINT: 521848b8605Smrg return &emit_R16_UINT; 522848b8605Smrg case PIPE_FORMAT_R16G16_UINT: 523848b8605Smrg return &emit_R16G16_UINT; 524848b8605Smrg case PIPE_FORMAT_R16G16B16_UINT: 525848b8605Smrg return &emit_R16G16B16_UINT; 526848b8605Smrg case PIPE_FORMAT_R16G16B16A16_UINT: 527848b8605Smrg return &emit_R16G16B16A16_UINT; 528848b8605Smrg 529848b8605Smrg case PIPE_FORMAT_R8_UINT: 530848b8605Smrg return &emit_R8_UINT; 531848b8605Smrg case PIPE_FORMAT_R8G8_UINT: 532848b8605Smrg return &emit_R8G8_UINT; 533848b8605Smrg case PIPE_FORMAT_R8G8B8_UINT: 534848b8605Smrg return &emit_R8G8B8_UINT; 535848b8605Smrg case PIPE_FORMAT_R8G8B8A8_UINT: 536848b8605Smrg return &emit_R8G8B8A8_UINT; 537848b8605Smrg 538848b8605Smrg case PIPE_FORMAT_R32_SINT: 539848b8605Smrg return &emit_R32_SINT; 540848b8605Smrg case PIPE_FORMAT_R32G32_SINT: 541848b8605Smrg return &emit_R32G32_SINT; 542848b8605Smrg case PIPE_FORMAT_R32G32B32_SINT: 543848b8605Smrg return &emit_R32G32B32_SINT; 544848b8605Smrg case PIPE_FORMAT_R32G32B32A32_SINT: 545848b8605Smrg return &emit_R32G32B32A32_SINT; 546848b8605Smrg 547848b8605Smrg case PIPE_FORMAT_R16_SINT: 548848b8605Smrg return &emit_R16_SINT; 549848b8605Smrg case PIPE_FORMAT_R16G16_SINT: 550848b8605Smrg return &emit_R16G16_SINT; 551848b8605Smrg case PIPE_FORMAT_R16G16B16_SINT: 552848b8605Smrg return &emit_R16G16B16_SINT; 553848b8605Smrg case PIPE_FORMAT_R16G16B16A16_SINT: 554848b8605Smrg return &emit_R16G16B16A16_SINT; 555848b8605Smrg 556848b8605Smrg case PIPE_FORMAT_R8_SINT: 557848b8605Smrg return &emit_R8_SINT; 558848b8605Smrg case PIPE_FORMAT_R8G8_SINT: 559848b8605Smrg return &emit_R8G8_SINT; 560848b8605Smrg case PIPE_FORMAT_R8G8B8_SINT: 561848b8605Smrg return &emit_R8G8B8_SINT; 562848b8605Smrg case PIPE_FORMAT_R8G8B8A8_SINT: 563848b8605Smrg return &emit_R8G8B8A8_SINT; 564848b8605Smrg 565848b8605Smrg case PIPE_FORMAT_B10G10R10A2_UNORM: 566848b8605Smrg return &emit_B10G10R10A2_UNORM; 567848b8605Smrg case PIPE_FORMAT_B10G10R10A2_USCALED: 568848b8605Smrg return &emit_B10G10R10A2_USCALED; 569848b8605Smrg case PIPE_FORMAT_B10G10R10A2_SNORM: 570848b8605Smrg return &emit_B10G10R10A2_SNORM; 571848b8605Smrg case PIPE_FORMAT_B10G10R10A2_SSCALED: 572848b8605Smrg return &emit_B10G10R10A2_SSCALED; 573848b8605Smrg 574848b8605Smrg case PIPE_FORMAT_R10G10B10A2_UNORM: 575848b8605Smrg return &emit_R10G10B10A2_UNORM; 576848b8605Smrg case PIPE_FORMAT_R10G10B10A2_USCALED: 577848b8605Smrg return &emit_R10G10B10A2_USCALED; 578848b8605Smrg case PIPE_FORMAT_R10G10B10A2_SNORM: 579848b8605Smrg return &emit_R10G10B10A2_SNORM; 580848b8605Smrg case PIPE_FORMAT_R10G10B10A2_SSCALED: 581848b8605Smrg return &emit_R10G10B10A2_SSCALED; 582848b8605Smrg 583848b8605Smrg default: 584b8e80941Smrg assert(0); 585848b8605Smrg return &emit_NULL; 586848b8605Smrg } 587848b8605Smrg} 588848b8605Smrg 589b8e80941Smrgstatic ALWAYS_INLINE void PIPE_CDECL 590b8e80941Smrggeneric_run_one(struct translate_generic *tg, 591b8e80941Smrg unsigned elt, 592b8e80941Smrg unsigned start_instance, 593b8e80941Smrg unsigned instance_id, 594b8e80941Smrg void *vert) 595848b8605Smrg{ 596848b8605Smrg unsigned nr_attrs = tg->nr_attrib; 597848b8605Smrg unsigned attr; 598848b8605Smrg 599848b8605Smrg for (attr = 0; attr < nr_attrs; attr++) { 600848b8605Smrg float data[4]; 601848b8605Smrg uint8_t *dst = (uint8_t *)vert + tg->attrib[attr].output_offset; 602848b8605Smrg 603848b8605Smrg if (tg->attrib[attr].type == TRANSLATE_ELEMENT_NORMAL) { 604848b8605Smrg const uint8_t *src; 605848b8605Smrg unsigned index; 606848b8605Smrg int copy_size; 607848b8605Smrg 608848b8605Smrg if (tg->attrib[attr].instance_divisor) { 609848b8605Smrg index = start_instance; 610848b8605Smrg index += (instance_id / tg->attrib[attr].instance_divisor); 611848b8605Smrg /* XXX we need to clamp the index here too, but to a 612848b8605Smrg * per-array max value, not the draw->pt.max_index value 613848b8605Smrg * that's being given to us via translate->set_buffer(). 614848b8605Smrg */ 615848b8605Smrg } 616848b8605Smrg else { 617848b8605Smrg index = elt; 618848b8605Smrg /* clamp to avoid going out of bounds */ 619848b8605Smrg index = MIN2(index, tg->attrib[attr].max_index); 620848b8605Smrg } 621848b8605Smrg 622848b8605Smrg src = tg->attrib[attr].input_ptr + 623848b8605Smrg (ptrdiff_t)tg->attrib[attr].input_stride * index; 624848b8605Smrg 625848b8605Smrg copy_size = tg->attrib[attr].copy_size; 626b8e80941Smrg if (likely(copy_size >= 0)) { 627848b8605Smrg memcpy(dst, src, copy_size); 628b8e80941Smrg } else { 629b8e80941Smrg tg->attrib[attr].fetch(data, src, 0, 0); 630848b8605Smrg 631848b8605Smrg if (0) 632848b8605Smrg debug_printf("Fetch linear attr %d from %p stride %d index %d: " 633848b8605Smrg " %f, %f, %f, %f \n", 634848b8605Smrg attr, 635848b8605Smrg tg->attrib[attr].input_ptr, 636848b8605Smrg tg->attrib[attr].input_stride, 637848b8605Smrg index, 638848b8605Smrg data[0], data[1],data[2], data[3]); 639848b8605Smrg 640b8e80941Smrg tg->attrib[attr].emit(data, dst); 641848b8605Smrg } 642848b8605Smrg } else { 643b8e80941Smrg if (likely(tg->attrib[attr].copy_size >= 0)) { 644848b8605Smrg memcpy(data, &instance_id, 4); 645b8e80941Smrg } else { 646848b8605Smrg data[0] = (float)instance_id; 647b8e80941Smrg tg->attrib[attr].emit(data, dst); 648848b8605Smrg } 649848b8605Smrg } 650848b8605Smrg } 651848b8605Smrg} 652848b8605Smrg 653848b8605Smrg/** 654848b8605Smrg * Fetch vertex attributes for 'count' vertices. 655848b8605Smrg */ 656b8e80941Smrgstatic void PIPE_CDECL 657b8e80941Smrggeneric_run_elts(struct translate *translate, 658b8e80941Smrg const unsigned *elts, 659b8e80941Smrg unsigned count, 660b8e80941Smrg unsigned start_instance, 661b8e80941Smrg unsigned instance_id, 662b8e80941Smrg void *output_buffer) 663848b8605Smrg{ 664848b8605Smrg struct translate_generic *tg = translate_generic(translate); 665848b8605Smrg char *vert = output_buffer; 666848b8605Smrg unsigned i; 667848b8605Smrg 668848b8605Smrg for (i = 0; i < count; i++) { 669848b8605Smrg generic_run_one(tg, *elts++, start_instance, instance_id, vert); 670848b8605Smrg vert += tg->translate.key.output_stride; 671848b8605Smrg } 672848b8605Smrg} 673848b8605Smrg 674b8e80941Smrgstatic void PIPE_CDECL 675b8e80941Smrggeneric_run_elts16(struct translate *translate, 676b8e80941Smrg const uint16_t *elts, 677b8e80941Smrg unsigned count, 678b8e80941Smrg unsigned start_instance, 679b8e80941Smrg unsigned instance_id, 680b8e80941Smrg void *output_buffer) 681848b8605Smrg{ 682848b8605Smrg struct translate_generic *tg = translate_generic(translate); 683848b8605Smrg char *vert = output_buffer; 684848b8605Smrg unsigned i; 685848b8605Smrg 686848b8605Smrg for (i = 0; i < count; i++) { 687848b8605Smrg generic_run_one(tg, *elts++, start_instance, instance_id, vert); 688848b8605Smrg vert += tg->translate.key.output_stride; 689848b8605Smrg } 690848b8605Smrg} 691848b8605Smrg 692b8e80941Smrgstatic void PIPE_CDECL 693b8e80941Smrggeneric_run_elts8(struct translate *translate, 694b8e80941Smrg const uint8_t *elts, 695b8e80941Smrg unsigned count, 696b8e80941Smrg unsigned start_instance, 697b8e80941Smrg unsigned instance_id, 698b8e80941Smrg void *output_buffer) 699848b8605Smrg{ 700848b8605Smrg struct translate_generic *tg = translate_generic(translate); 701848b8605Smrg char *vert = output_buffer; 702848b8605Smrg unsigned i; 703848b8605Smrg 704848b8605Smrg for (i = 0; i < count; i++) { 705848b8605Smrg generic_run_one(tg, *elts++, start_instance, instance_id, vert); 706848b8605Smrg vert += tg->translate.key.output_stride; 707848b8605Smrg } 708848b8605Smrg} 709848b8605Smrg 710b8e80941Smrgstatic void PIPE_CDECL 711b8e80941Smrggeneric_run(struct translate *translate, 712b8e80941Smrg unsigned start, 713b8e80941Smrg unsigned count, 714b8e80941Smrg unsigned start_instance, 715b8e80941Smrg unsigned instance_id, 716b8e80941Smrg void *output_buffer) 717848b8605Smrg{ 718848b8605Smrg struct translate_generic *tg = translate_generic(translate); 719848b8605Smrg char *vert = output_buffer; 720848b8605Smrg unsigned i; 721848b8605Smrg 722848b8605Smrg for (i = 0; i < count; i++) { 723848b8605Smrg generic_run_one(tg, start + i, start_instance, instance_id, vert); 724848b8605Smrg vert += tg->translate.key.output_stride; 725848b8605Smrg } 726848b8605Smrg} 727848b8605Smrg 728848b8605Smrg 729b8e80941Smrg 730b8e80941Smrgstatic void 731b8e80941Smrggeneric_set_buffer(struct translate *translate, 732b8e80941Smrg unsigned buf, 733b8e80941Smrg const void *ptr, 734b8e80941Smrg unsigned stride, 735b8e80941Smrg unsigned max_index) 736848b8605Smrg{ 737848b8605Smrg struct translate_generic *tg = translate_generic(translate); 738848b8605Smrg unsigned i; 739848b8605Smrg 740848b8605Smrg for (i = 0; i < tg->nr_attrib; i++) { 741848b8605Smrg if (tg->attrib[i].buffer == buf) { 742b8e80941Smrg tg->attrib[i].input_ptr = ((const uint8_t *)ptr + 743b8e80941Smrg tg->attrib[i].input_offset); 744b8e80941Smrg tg->attrib[i].input_stride = stride; 745848b8605Smrg tg->attrib[i].max_index = max_index; 746848b8605Smrg } 747848b8605Smrg } 748848b8605Smrg} 749848b8605Smrg 750848b8605Smrg 751b8e80941Smrgstatic void 752b8e80941Smrggeneric_release(struct translate *translate) 753848b8605Smrg{ 754848b8605Smrg /* Refcount? 755848b8605Smrg */ 756848b8605Smrg FREE(translate); 757848b8605Smrg} 758848b8605Smrg 759848b8605Smrgstatic boolean 760b8e80941Smrgis_legal_int_format_combo(const struct util_format_description *src, 761b8e80941Smrg const struct util_format_description *dst) 762848b8605Smrg{ 763848b8605Smrg unsigned i; 764848b8605Smrg unsigned nr = MIN2(src->nr_channels, dst->nr_channels); 765848b8605Smrg 766848b8605Smrg for (i = 0; i < nr; i++) { 767848b8605Smrg /* The signs must match. */ 768848b8605Smrg if (src->channel[i].type != dst->channel[i].type) { 769848b8605Smrg return FALSE; 770848b8605Smrg } 771848b8605Smrg 772848b8605Smrg /* Integers must not lose precision at any point in the pipeline. */ 773848b8605Smrg if (src->channel[i].size > dst->channel[i].size) { 774848b8605Smrg return FALSE; 775848b8605Smrg } 776848b8605Smrg } 777848b8605Smrg return TRUE; 778848b8605Smrg} 779848b8605Smrg 780b8e80941Smrgstruct translate * 781b8e80941Smrgtranslate_generic_create(const struct translate_key *key) 782848b8605Smrg{ 783848b8605Smrg struct translate_generic *tg = CALLOC_STRUCT(translate_generic); 784848b8605Smrg unsigned i; 785848b8605Smrg 786b8e80941Smrg if (!tg) 787848b8605Smrg return NULL; 788848b8605Smrg 789848b8605Smrg assert(key->nr_elements <= TRANSLATE_MAX_ATTRIBS); 790848b8605Smrg 791848b8605Smrg tg->translate.key = *key; 792848b8605Smrg tg->translate.release = generic_release; 793848b8605Smrg tg->translate.set_buffer = generic_set_buffer; 794848b8605Smrg tg->translate.run_elts = generic_run_elts; 795848b8605Smrg tg->translate.run_elts16 = generic_run_elts16; 796848b8605Smrg tg->translate.run_elts8 = generic_run_elts8; 797848b8605Smrg tg->translate.run = generic_run; 798848b8605Smrg 799848b8605Smrg for (i = 0; i < key->nr_elements; i++) { 800848b8605Smrg const struct util_format_description *format_desc = 801848b8605Smrg util_format_description(key->element[i].input_format); 802848b8605Smrg 803848b8605Smrg assert(format_desc); 804848b8605Smrg 805848b8605Smrg tg->attrib[i].type = key->element[i].type; 806848b8605Smrg 807848b8605Smrg if (format_desc->channel[0].pure_integer) { 808848b8605Smrg const struct util_format_description *out_format_desc = 809848b8605Smrg util_format_description(key->element[i].output_format); 810848b8605Smrg 811848b8605Smrg if (!is_legal_int_format_combo(format_desc, out_format_desc)) { 812848b8605Smrg FREE(tg); 813848b8605Smrg return NULL; 814848b8605Smrg } 815848b8605Smrg 816848b8605Smrg if (format_desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED) { 817848b8605Smrg assert(format_desc->fetch_rgba_sint); 818848b8605Smrg tg->attrib[i].fetch = (fetch_func)format_desc->fetch_rgba_sint; 819848b8605Smrg } else { 820848b8605Smrg assert(format_desc->fetch_rgba_uint); 821848b8605Smrg tg->attrib[i].fetch = (fetch_func)format_desc->fetch_rgba_uint; 822848b8605Smrg } 823848b8605Smrg } else { 824848b8605Smrg assert(format_desc->fetch_rgba_float); 825848b8605Smrg tg->attrib[i].fetch = (fetch_func)format_desc->fetch_rgba_float; 826848b8605Smrg } 827848b8605Smrg 828848b8605Smrg tg->attrib[i].buffer = key->element[i].input_buffer; 829848b8605Smrg tg->attrib[i].input_offset = key->element[i].input_offset; 830848b8605Smrg tg->attrib[i].instance_divisor = key->element[i].instance_divisor; 831848b8605Smrg 832848b8605Smrg tg->attrib[i].output_offset = key->element[i].output_offset; 833848b8605Smrg 834848b8605Smrg tg->attrib[i].copy_size = -1; 835b8e80941Smrg if (tg->attrib[i].type == TRANSLATE_ELEMENT_INSTANCE_ID) { 836b8e80941Smrg if (key->element[i].output_format == PIPE_FORMAT_R32_USCALED 837b8e80941Smrg || key->element[i].output_format == PIPE_FORMAT_R32_SSCALED) 838b8e80941Smrg tg->attrib[i].copy_size = 4; 839b8e80941Smrg } else { 840b8e80941Smrg if (key->element[i].input_format == key->element[i].output_format 841b8e80941Smrg && format_desc->block.width == 1 842b8e80941Smrg && format_desc->block.height == 1 843b8e80941Smrg && !(format_desc->block.bits & 7)) 844848b8605Smrg tg->attrib[i].copy_size = format_desc->block.bits >> 3; 845848b8605Smrg } 846848b8605Smrg 847b8e80941Smrg if (tg->attrib[i].copy_size < 0) 848b8e80941Smrg tg->attrib[i].emit = get_emit_func(key->element[i].output_format); 849848b8605Smrg else 850b8e80941Smrg tg->attrib[i].emit = NULL; 851848b8605Smrg } 852848b8605Smrg 853848b8605Smrg tg->nr_attrib = key->nr_elements; 854848b8605Smrg 855848b8605Smrg return &tg->translate; 856848b8605Smrg} 857848b8605Smrg 858b8e80941Smrgboolean 859b8e80941Smrgtranslate_generic_is_output_format_supported(enum pipe_format format) 860848b8605Smrg{ 861b8e80941Smrg switch(format) { 862848b8605Smrg case PIPE_FORMAT_R64G64B64A64_FLOAT: return TRUE; 863848b8605Smrg case PIPE_FORMAT_R64G64B64_FLOAT: return TRUE; 864848b8605Smrg case PIPE_FORMAT_R64G64_FLOAT: return TRUE; 865848b8605Smrg case PIPE_FORMAT_R64_FLOAT: return TRUE; 866848b8605Smrg 867848b8605Smrg case PIPE_FORMAT_R32G32B32A32_FLOAT: return TRUE; 868848b8605Smrg case PIPE_FORMAT_R32G32B32_FLOAT: return TRUE; 869848b8605Smrg case PIPE_FORMAT_R32G32_FLOAT: return TRUE; 870848b8605Smrg case PIPE_FORMAT_R32_FLOAT: return TRUE; 871848b8605Smrg 872848b8605Smrg case PIPE_FORMAT_R16G16B16A16_FLOAT: return TRUE; 873848b8605Smrg case PIPE_FORMAT_R16G16B16_FLOAT: return TRUE; 874848b8605Smrg case PIPE_FORMAT_R16G16_FLOAT: return TRUE; 875848b8605Smrg case PIPE_FORMAT_R16_FLOAT: return TRUE; 876848b8605Smrg 877848b8605Smrg case PIPE_FORMAT_R32G32B32A32_USCALED: return TRUE; 878848b8605Smrg case PIPE_FORMAT_R32G32B32_USCALED: return TRUE; 879848b8605Smrg case PIPE_FORMAT_R32G32_USCALED: return TRUE; 880848b8605Smrg case PIPE_FORMAT_R32_USCALED: return TRUE; 881848b8605Smrg 882848b8605Smrg case PIPE_FORMAT_R32G32B32A32_SSCALED: return TRUE; 883848b8605Smrg case PIPE_FORMAT_R32G32B32_SSCALED: return TRUE; 884848b8605Smrg case PIPE_FORMAT_R32G32_SSCALED: return TRUE; 885848b8605Smrg case PIPE_FORMAT_R32_SSCALED: return TRUE; 886848b8605Smrg 887848b8605Smrg case PIPE_FORMAT_R32G32B32A32_UNORM: return TRUE; 888848b8605Smrg case PIPE_FORMAT_R32G32B32_UNORM: return TRUE; 889848b8605Smrg case PIPE_FORMAT_R32G32_UNORM: return TRUE; 890848b8605Smrg case PIPE_FORMAT_R32_UNORM: return TRUE; 891848b8605Smrg 892848b8605Smrg case PIPE_FORMAT_R32G32B32A32_SNORM: return TRUE; 893848b8605Smrg case PIPE_FORMAT_R32G32B32_SNORM: return TRUE; 894848b8605Smrg case PIPE_FORMAT_R32G32_SNORM: return TRUE; 895848b8605Smrg case PIPE_FORMAT_R32_SNORM: return TRUE; 896848b8605Smrg 897848b8605Smrg case PIPE_FORMAT_R16G16B16A16_USCALED: return TRUE; 898848b8605Smrg case PIPE_FORMAT_R16G16B16_USCALED: return TRUE; 899848b8605Smrg case PIPE_FORMAT_R16G16_USCALED: return TRUE; 900848b8605Smrg case PIPE_FORMAT_R16_USCALED: return TRUE; 901848b8605Smrg 902848b8605Smrg case PIPE_FORMAT_R16G16B16A16_SSCALED: return TRUE; 903848b8605Smrg case PIPE_FORMAT_R16G16B16_SSCALED: return TRUE; 904848b8605Smrg case PIPE_FORMAT_R16G16_SSCALED: return TRUE; 905848b8605Smrg case PIPE_FORMAT_R16_SSCALED: return TRUE; 906848b8605Smrg 907848b8605Smrg case PIPE_FORMAT_R16G16B16A16_UNORM: return TRUE; 908848b8605Smrg case PIPE_FORMAT_R16G16B16_UNORM: return TRUE; 909848b8605Smrg case PIPE_FORMAT_R16G16_UNORM: return TRUE; 910848b8605Smrg case PIPE_FORMAT_R16_UNORM: return TRUE; 911848b8605Smrg 912848b8605Smrg case PIPE_FORMAT_R16G16B16A16_SNORM: return TRUE; 913848b8605Smrg case PIPE_FORMAT_R16G16B16_SNORM: return TRUE; 914848b8605Smrg case PIPE_FORMAT_R16G16_SNORM: return TRUE; 915848b8605Smrg case PIPE_FORMAT_R16_SNORM: return TRUE; 916848b8605Smrg 917848b8605Smrg case PIPE_FORMAT_R8G8B8A8_USCALED: return TRUE; 918848b8605Smrg case PIPE_FORMAT_R8G8B8_USCALED: return TRUE; 919848b8605Smrg case PIPE_FORMAT_R8G8_USCALED: return TRUE; 920848b8605Smrg case PIPE_FORMAT_R8_USCALED: return TRUE; 921848b8605Smrg 922848b8605Smrg case PIPE_FORMAT_R8G8B8A8_SSCALED: return TRUE; 923848b8605Smrg case PIPE_FORMAT_R8G8B8_SSCALED: return TRUE; 924848b8605Smrg case PIPE_FORMAT_R8G8_SSCALED: return TRUE; 925848b8605Smrg case PIPE_FORMAT_R8_SSCALED: return TRUE; 926848b8605Smrg 927848b8605Smrg case PIPE_FORMAT_R8G8B8A8_UNORM: return TRUE; 928848b8605Smrg case PIPE_FORMAT_R8G8B8_UNORM: return TRUE; 929848b8605Smrg case PIPE_FORMAT_R8G8_UNORM: return TRUE; 930848b8605Smrg case PIPE_FORMAT_R8_UNORM: return TRUE; 931848b8605Smrg 932848b8605Smrg case PIPE_FORMAT_R8G8B8A8_SNORM: return TRUE; 933848b8605Smrg case PIPE_FORMAT_R8G8B8_SNORM: return TRUE; 934848b8605Smrg case PIPE_FORMAT_R8G8_SNORM: return TRUE; 935848b8605Smrg case PIPE_FORMAT_R8_SNORM: return TRUE; 936848b8605Smrg 937848b8605Smrg case PIPE_FORMAT_A8R8G8B8_UNORM: return TRUE; 938848b8605Smrg case PIPE_FORMAT_B8G8R8A8_UNORM: return TRUE; 939848b8605Smrg 940848b8605Smrg case PIPE_FORMAT_R32G32B32A32_UINT: return TRUE; 941848b8605Smrg case PIPE_FORMAT_R32G32B32_UINT: return TRUE; 942848b8605Smrg case PIPE_FORMAT_R32G32_UINT: return TRUE; 943848b8605Smrg case PIPE_FORMAT_R32_UINT: return TRUE; 944848b8605Smrg 945848b8605Smrg case PIPE_FORMAT_R16G16B16A16_UINT: return TRUE; 946848b8605Smrg case PIPE_FORMAT_R16G16B16_UINT: return TRUE; 947848b8605Smrg case PIPE_FORMAT_R16G16_UINT: return TRUE; 948848b8605Smrg case PIPE_FORMAT_R16_UINT: return TRUE; 949848b8605Smrg 950848b8605Smrg case PIPE_FORMAT_R8G8B8A8_UINT: return TRUE; 951848b8605Smrg case PIPE_FORMAT_R8G8B8_UINT: return TRUE; 952848b8605Smrg case PIPE_FORMAT_R8G8_UINT: return TRUE; 953848b8605Smrg case PIPE_FORMAT_R8_UINT: return TRUE; 954848b8605Smrg 955848b8605Smrg case PIPE_FORMAT_R32G32B32A32_SINT: return TRUE; 956848b8605Smrg case PIPE_FORMAT_R32G32B32_SINT: return TRUE; 957848b8605Smrg case PIPE_FORMAT_R32G32_SINT: return TRUE; 958848b8605Smrg case PIPE_FORMAT_R32_SINT: return TRUE; 959848b8605Smrg 960848b8605Smrg case PIPE_FORMAT_R16G16B16A16_SINT: return TRUE; 961848b8605Smrg case PIPE_FORMAT_R16G16B16_SINT: return TRUE; 962848b8605Smrg case PIPE_FORMAT_R16G16_SINT: return TRUE; 963848b8605Smrg case PIPE_FORMAT_R16_SINT: return TRUE; 964848b8605Smrg 965848b8605Smrg case PIPE_FORMAT_R8G8B8A8_SINT: return TRUE; 966848b8605Smrg case PIPE_FORMAT_R8G8B8_SINT: return TRUE; 967848b8605Smrg case PIPE_FORMAT_R8G8_SINT: return TRUE; 968848b8605Smrg case PIPE_FORMAT_R8_SINT: return TRUE; 969848b8605Smrg 970848b8605Smrg case PIPE_FORMAT_B10G10R10A2_UNORM: return TRUE; 971848b8605Smrg case PIPE_FORMAT_B10G10R10A2_USCALED: return TRUE; 972848b8605Smrg case PIPE_FORMAT_B10G10R10A2_SNORM: return TRUE; 973848b8605Smrg case PIPE_FORMAT_B10G10R10A2_SSCALED: return TRUE; 974848b8605Smrg 975848b8605Smrg case PIPE_FORMAT_R10G10B10A2_UNORM: return TRUE; 976848b8605Smrg case PIPE_FORMAT_R10G10B10A2_USCALED: return TRUE; 977848b8605Smrg case PIPE_FORMAT_R10G10B10A2_SNORM: return TRUE; 978848b8605Smrg case PIPE_FORMAT_R10G10B10A2_SSCALED: return TRUE; 979848b8605Smrg 980848b8605Smrg default: return FALSE; 981848b8605Smrg } 982848b8605Smrg} 983