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