Home | History | Annotate | Download | only in llvmpipe
      1 #!/usr/bin/env python
      2 
      3 CopyRight = '''
      4 /**************************************************************************
      5  *
      6  * Copyright 2009 VMware, Inc.
      7  * All Rights Reserved.
      8  *
      9  * Permission is hereby granted, free of charge, to any person obtaining a
     10  * copy of this software and associated documentation files (the
     11  * "Software"), to deal in the Software without restriction, including
     12  * without limitation the rights to use, copy, modify, merge, publish,
     13  * distribute, sub license, and/or sell copies of the Software, and to
     14  * permit persons to whom the Software is furnished to do so, subject to
     15  * the following conditions:
     16  *
     17  * The above copyright notice and this permission notice (including the
     18  * next paragraph) shall be included in all copies or substantial portions
     19  * of the Software.
     20  *
     21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     22  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     24  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
     25  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     26  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     27  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     28  *
     29  **************************************************************************/
     30 
     31 /**
     32  * @file
     33  * Pixel format accessor functions.
     34  *
     35  * @author Jose Fonseca <jfonseca (at] vmware.com>
     36  */
     37 '''
     38 
     39 
     40 import sys
     41 import os.path
     42 
     43 sys.path.insert(0, os.path.join(os.path.dirname(sys.argv[0]), '../../auxiliary/util'))
     44 
     45 from u_format_pack import *
     46 
     47 
     48 def is_format_supported(format):
     49     '''Determines whether we actually have the plumbing necessary to generate the 
     50     to read/write to/from this format.'''
     51 
     52     # FIXME: Ideally we would support any format combination here.
     53 
     54     if format.name == 'PIPE_FORMAT_R11G11B10_FLOAT':
     55         return True;
     56 
     57     if format.name == 'PIPE_FORMAT_R9G9B9E5_FLOAT':
     58         return True;
     59 
     60     if format.layout != PLAIN:
     61         return False
     62 
     63     for i in range(4):
     64         channel = format.channels[i]
     65         if channel.type not in (VOID, UNSIGNED, SIGNED, FLOAT):
     66             return False
     67         if channel.type == FLOAT and channel.size not in (16, 32 ,64):
     68             return False
     69 
     70     if format.colorspace not in ('rgb', 'srgb'):
     71         return False
     72 
     73     return True
     74 
     75 
     76 def generate_format_read(format, dst_channel, dst_native_type, dst_suffix):
     77     '''Generate the function to read pixels from a particular format'''
     78 
     79     name = format.short_name()
     80 
     81     src_native_type = native_type(format)
     82 
     83     print 'static void'
     84     print 'lp_tile_%s_swizzle_%s(%s * restrict dst, const uint8_t * restrict src, unsigned src_stride, unsigned x0, unsigned y0)' % (name, dst_suffix, dst_native_type)
     85     print '{'
     86     print '   unsigned x, y;'
     87     print '   const uint8_t *src_row = src + y0*src_stride;'
     88     print '   for (y = 0; y < TILE_SIZE; ++y) {'
     89     print '      const %s *src_pixel = (const %s *)(src_row + x0*%u);' % (src_native_type, src_native_type, format.stride())
     90     print '      for (x = 0; x < TILE_SIZE; ++x) {'
     91 
     92     names = ['']*4
     93     if format.colorspace in ('rgb', 'srgb'):
     94         for i in range(4):
     95             swizzle = format.swizzles[i]
     96             if swizzle < 4:
     97                 names[swizzle] += 'rgba'[i]
     98     elif format.colorspace == 'zs':
     99         swizzle = format.swizzles[0]
    100         if swizzle < 4:
    101             names[swizzle] = 'z'
    102         else:
    103             assert False
    104     else:
    105         assert False
    106 
    107     if format.name == 'PIPE_FORMAT_R11G11B10_FLOAT':
    108         print '         float tmp[3];'
    109         print '         uint8_t r, g, b;'
    110         print '         r11g11b10f_to_float3(*src_pixel++, tmp);'
    111         for i in range(3):
    112             print '         %s = tmp[%d] * 0xff;' % (names[i], i)
    113     elif format.name == 'PIPE_FORMAT_R9G9B9E5_FLOAT':
    114         print '         float tmp[3];'
    115         print '         uint8_t r, g, b;'
    116         print '         rgb9e5_to_float3(*src_pixel++, tmp);'
    117         for i in range(3):
    118             print '         %s = tmp[%d] * 0xff;' % (names[i], i)
    119     elif format.layout == PLAIN:
    120         if not format.is_array():
    121             print '         %s pixel = *src_pixel++;' % src_native_type
    122             shift = 0;
    123             for i in range(4):
    124                 src_channel = format.channels[i]
    125                 width = src_channel.size
    126                 if names[i]:
    127                     value = 'pixel'
    128                     mask = (1 << width) - 1
    129                     if shift:
    130                         value = '(%s >> %u)' % (value, shift)
    131                     if shift + width < format.block_size():
    132                         value = '(%s & 0x%x)' % (value, mask)
    133                     value = conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=False)
    134                     print '         %s %s = %s;' % (dst_native_type, names[i], value)
    135                 shift += width
    136         else:
    137             for i in range(4):
    138                 if names[i]:
    139                     print '         %s %s;' % (dst_native_type, names[i])
    140             for i in range(4):
    141                 src_channel = format.channels[i]
    142                 if names[i]:
    143                     value = '(*src_pixel++)'
    144                     value = conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=False)
    145                     print '         %s = %s;' % (names[i], value)
    146                 elif src_channel.size:
    147                     print '         ++src_pixel;'
    148     else:
    149         assert False
    150 
    151     for i in range(4):
    152         if format.colorspace in ('rgb', 'srgb'):
    153             swizzle = format.swizzles[i]
    154             if swizzle < 4:
    155                 value = names[swizzle]
    156             elif swizzle == SWIZZLE_0:
    157                 value = '0'
    158             elif swizzle == SWIZZLE_1:
    159                 value = get_one(dst_channel)
    160             else:
    161                 assert False
    162         elif format.colorspace == 'zs':
    163             if i < 3:
    164                 value = 'z'
    165             else:
    166                 value = get_one(dst_channel)
    167         else:
    168             assert False
    169         print '         TILE_PIXEL(dst, x, y, %u) = %s; /* %s */' % (i, value, 'rgba'[i])
    170 
    171     print '      }'
    172     print '      src_row += src_stride;'
    173     print '   }'
    174     print '}'
    175     print
    176     
    177 
    178 def pack_rgba(format, src_channel, r, g, b, a):
    179     """Return an expression for packing r, g, b, a into a pixel of the
    180     given format.  Ex: '(b << 24) | (g << 16) | (r << 8) | (a << 0)'
    181     """
    182     assert format.colorspace in ('rgb', 'srgb')
    183     inv_swizzle = format.inv_swizzles()
    184     shift = 0
    185     expr = None
    186     for i in range(4):
    187         # choose r, g, b, or a depending on the inverse swizzle term
    188         if inv_swizzle[i] == 0:
    189             value = r
    190         elif inv_swizzle[i] == 1:
    191             value = g
    192         elif inv_swizzle[i] == 2:
    193             value = b
    194         elif inv_swizzle[i] == 3:
    195             value = a
    196         else:
    197             value = None
    198 
    199         if value:
    200             dst_channel = format.channels[i]
    201             dst_native_type = native_type(format)
    202             value = conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=False)
    203             term = "((%s) << %d)" % (value, shift)
    204             if expr:
    205                 expr = expr + " | " + term
    206             else:
    207                 expr = term
    208 
    209         width = format.channels[i].size
    210         shift = shift + width
    211     return expr
    212 
    213 
    214 def emit_unrolled_unswizzle_code(format, src_channel):
    215     '''Emit code for writing a block based on unrolled loops.
    216     This is considerably faster than the TILE_PIXEL-based code below.
    217     '''
    218     dst_native_type = 'uint%u_t' % format.block_size()
    219     print '   const unsigned dstpix_stride = dst_stride / %d;' % format.stride()
    220     print '   %s *dstpix = (%s *) dst;' % (dst_native_type, dst_native_type)
    221     print '   unsigned int qx, qy, i;'
    222     print
    223     print '   for (qy = 0; qy < TILE_SIZE; qy += TILE_VECTOR_HEIGHT) {'
    224     print '      const unsigned py = y0 + qy;'
    225     print '      for (qx = 0; qx < TILE_SIZE; qx += TILE_VECTOR_WIDTH) {'
    226     print '         const unsigned px = x0 + qx;'
    227     print '         const uint8_t *r = src + 0 * TILE_C_STRIDE;'
    228     print '         const uint8_t *g = src + 1 * TILE_C_STRIDE;'
    229     print '         const uint8_t *b = src + 2 * TILE_C_STRIDE;'
    230     print '         const uint8_t *a = src + 3 * TILE_C_STRIDE;'
    231     print '         (void) r; (void) g; (void) b; (void) a; /* silence warnings */'
    232     print '         for (i = 0; i < TILE_C_STRIDE; i += 2) {'
    233     print '            const uint32_t pixel0 = %s;' % pack_rgba(format, src_channel, "r[i+0]", "g[i+0]", "b[i+0]", "a[i+0]")
    234     print '            const uint32_t pixel1 = %s;' % pack_rgba(format, src_channel, "r[i+1]", "g[i+1]", "b[i+1]", "a[i+1]")
    235     print '            const unsigned offset = (py + tile_y_offset[i]) * dstpix_stride + (px + tile_x_offset[i]);'
    236     print '            dstpix[offset + 0] = pixel0;'
    237     print '            dstpix[offset + 1] = pixel1;'
    238     print '         }'
    239     print '         src += TILE_X_STRIDE;'
    240     print '      }'
    241     print '   }'
    242 
    243 
    244 def emit_tile_pixel_unswizzle_code(format, src_channel):
    245     '''Emit code for writing a block based on the TILE_PIXEL macro.'''
    246     dst_native_type = native_type(format)
    247 
    248     inv_swizzle = format.inv_swizzles()
    249 
    250     print '   unsigned x, y;'
    251     print '   uint8_t *dst_row = dst + y0*dst_stride;'
    252     print '   for (y = 0; y < TILE_SIZE; ++y) {'
    253     print '      %s *dst_pixel = (%s *)(dst_row + x0*%u);' % (dst_native_type, dst_native_type, format.stride())
    254     print '      for (x = 0; x < TILE_SIZE; ++x) {'
    255 
    256     if format.name == 'PIPE_FORMAT_R11G11B10_FLOAT':
    257         print '         float tmp[3];'
    258         for i in range(3):
    259             print '         tmp[%d] = ubyte_to_float(TILE_PIXEL(src, x, y, %u));' % (i, inv_swizzle[i])
    260         print '         *dst_pixel++ = float3_to_r11g11b10f(tmp);'
    261     elif format.name == 'PIPE_FORMAT_R9G9B9E5_FLOAT':
    262         print '         float tmp[3];'
    263         for i in range(3):
    264             print '         tmp[%d] = ubyte_to_float(TILE_PIXEL(src, x, y, %u));' % (i, inv_swizzle[i])
    265         print '         *dst_pixel++ = float3_to_rgb9e5(tmp);'
    266     elif format.layout == PLAIN:
    267         if not format.is_array():
    268             print '         %s pixel = 0;' % dst_native_type
    269             shift = 0;
    270             for i in range(4):
    271                 dst_channel = format.channels[i]
    272                 width = dst_channel.size
    273                 if inv_swizzle[i] is not None:
    274                     value = 'TILE_PIXEL(src, x, y, %u)' % inv_swizzle[i]
    275                     value = conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=False)
    276                     if shift:
    277                         value = '(%s << %u)' % (value, shift)
    278                     print '         pixel |= %s;' % value
    279                 shift += width
    280             print '         *dst_pixel++ = pixel;'
    281         else:
    282             for i in range(4):
    283                 dst_channel = format.channels[i]
    284                 if inv_swizzle[i] is not None:
    285                     value = 'TILE_PIXEL(src, x, y, %u)' % inv_swizzle[i]
    286                     value = conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=False)
    287                     print '         *dst_pixel++ = %s;' % value
    288                 elif dst_channel.size:
    289                     print '         ++dst_pixel;'
    290     else:
    291         assert False
    292 
    293     print '      }'
    294     print '      dst_row += dst_stride;'
    295     print '   }'
    296 
    297 
    298 def generate_format_write(format, src_channel, src_native_type, src_suffix):
    299     '''Generate the function to write pixels to a particular format'''
    300 
    301     name = format.short_name()
    302 
    303     print 'static void'
    304     print 'lp_tile_%s_unswizzle_%s(const %s * restrict src, uint8_t * restrict dst, unsigned dst_stride, unsigned x0, unsigned y0)' % (name, src_suffix, src_native_type)
    305     print '{'
    306     if format.layout == PLAIN \
    307         and format.colorspace == 'rgb' \
    308         and format.block_size() <= 32 \
    309         and format.is_pot() \
    310         and not format.is_mixed() \
    311         and (format.channels[0].type == UNSIGNED \
    312              or format.channels[1].type == UNSIGNED):
    313         emit_unrolled_unswizzle_code(format, src_channel)
    314     else:
    315         emit_tile_pixel_unswizzle_code(format, src_channel)
    316     print '}'
    317     print
    318     
    319 
    320 def generate_sse2():
    321     print '''
    322 #if defined(PIPE_ARCH_SSE)
    323 
    324 #include "util/u_sse.h"
    325 
    326 static ALWAYS_INLINE void 
    327 swz4( const __m128i * restrict x, 
    328       const __m128i * restrict y, 
    329       const __m128i * restrict z, 
    330       const __m128i * restrict w, 
    331       __m128i * restrict a, 
    332       __m128i * restrict b, 
    333       __m128i * restrict c, 
    334       __m128i * restrict d)
    335 {
    336    __m128i i, j, k, l;
    337    __m128i m, n, o, p;
    338    __m128i e, f, g, h;
    339 
    340    m = _mm_unpacklo_epi8(*x,*y);
    341    n = _mm_unpackhi_epi8(*x,*y);
    342    o = _mm_unpacklo_epi8(*z,*w);
    343    p = _mm_unpackhi_epi8(*z,*w);
    344 
    345    i = _mm_unpacklo_epi16(m,n);
    346    j = _mm_unpackhi_epi16(m,n);
    347    k = _mm_unpacklo_epi16(o,p);
    348    l = _mm_unpackhi_epi16(o,p);
    349 
    350    e = _mm_unpacklo_epi8(i,j);
    351    f = _mm_unpackhi_epi8(i,j);
    352    g = _mm_unpacklo_epi8(k,l);
    353    h = _mm_unpackhi_epi8(k,l);
    354 
    355    *a = _mm_unpacklo_epi64(e,g);
    356    *b = _mm_unpackhi_epi64(e,g);
    357    *c = _mm_unpacklo_epi64(f,h);
    358    *d = _mm_unpackhi_epi64(f,h);
    359 }
    360 
    361 static ALWAYS_INLINE void
    362 unswz4( const __m128i * restrict a, 
    363         const __m128i * restrict b, 
    364         const __m128i * restrict c, 
    365         const __m128i * restrict d, 
    366         __m128i * restrict x, 
    367         __m128i * restrict y, 
    368         __m128i * restrict z, 
    369         __m128i * restrict w)
    370 {
    371    __m128i i, j, k, l;
    372    __m128i m, n, o, p;
    373 
    374    i = _mm_unpacklo_epi8(*a,*b);
    375    j = _mm_unpackhi_epi8(*a,*b);
    376    k = _mm_unpacklo_epi8(*c,*d);
    377    l = _mm_unpackhi_epi8(*c,*d);
    378 
    379    m = _mm_unpacklo_epi16(i,k);
    380    n = _mm_unpackhi_epi16(i,k);
    381    o = _mm_unpacklo_epi16(j,l);
    382    p = _mm_unpackhi_epi16(j,l);
    383 
    384    *x = _mm_unpacklo_epi64(m,n);
    385    *y = _mm_unpackhi_epi64(m,n);
    386    *z = _mm_unpacklo_epi64(o,p);
    387    *w = _mm_unpackhi_epi64(o,p);
    388 }
    389 
    390 static void
    391 lp_tile_b8g8r8a8_unorm_swizzle_4ub_sse2(uint8_t * restrict dst,
    392                                         const uint8_t * restrict src, unsigned src_stride,
    393                                         unsigned x0, unsigned y0)
    394 {
    395    __m128i *dst128 = (__m128i *) dst;
    396    unsigned x, y;
    397    
    398    src += y0 * src_stride;
    399    src += x0 * sizeof(uint32_t);
    400 
    401    for (y = 0; y < TILE_SIZE; y += 4) {
    402       const uint8_t *src_row = src;
    403 
    404       for (x = 0; x < TILE_SIZE; x += 4) {
    405          swz4((const __m128i *) (src_row + 0 * src_stride),
    406               (const __m128i *) (src_row + 1 * src_stride),
    407               (const __m128i *) (src_row + 2 * src_stride),
    408               (const __m128i *) (src_row + 3 * src_stride),
    409               dst128 + 2,     /* b */
    410               dst128 + 1,     /* g */
    411               dst128 + 0,     /* r */
    412               dst128 + 3);    /* a */
    413 
    414          dst128 += 4;
    415          src_row += sizeof(__m128i);
    416       }
    417 
    418       src += 4 * src_stride;
    419    }
    420 }
    421 
    422 static void
    423 lp_tile_b8g8r8a8_unorm_unswizzle_4ub_sse2(const uint8_t * restrict src,
    424                                           uint8_t * restrict dst, unsigned dst_stride,
    425                                           unsigned x0, unsigned y0)
    426 {
    427    unsigned int x, y;
    428    const __m128i *src128 = (const __m128i *) src;
    429    
    430    dst += y0 * dst_stride;
    431    dst += x0 * sizeof(uint32_t);
    432    
    433    for (y = 0; y < TILE_SIZE; y += 4) {
    434       const uint8_t *dst_row = dst;
    435 
    436       for (x = 0; x < TILE_SIZE; x += 4) {
    437          unswz4( &src128[2],     /* b */
    438                  &src128[1],     /* g */
    439                  &src128[0],     /* r */
    440                  &src128[3],     /* a */
    441                  (__m128i *) (dst_row + 0 * dst_stride),
    442                  (__m128i *) (dst_row + 1 * dst_stride),
    443                  (__m128i *) (dst_row + 2 * dst_stride),
    444                  (__m128i *) (dst_row + 3 * dst_stride));
    445 
    446          src128 += 4;
    447          dst_row += sizeof(__m128i);;
    448       }
    449 
    450       dst += 4 * dst_stride;
    451    }
    452 }
    453 
    454 static void
    455 lp_tile_b8g8r8x8_unorm_swizzle_4ub_sse2(uint8_t * restrict dst,
    456                                         const uint8_t * restrict src, unsigned src_stride,
    457                                         unsigned x0, unsigned y0)
    458 {
    459    __m128i *dst128 = (__m128i *) dst;
    460    unsigned x, y;
    461 
    462    src += y0 * src_stride;
    463    src += x0 * sizeof(uint32_t);
    464 
    465    for (y = 0; y < TILE_SIZE; y += 4) {
    466       const uint8_t *src_row = src;
    467 
    468       for (x = 0; x < TILE_SIZE; x += 4) {
    469          swz4((const __m128i *) (src_row + 0 * src_stride),
    470               (const __m128i *) (src_row + 1 * src_stride),
    471               (const __m128i *) (src_row + 2 * src_stride),
    472               (const __m128i *) (src_row + 3 * src_stride),
    473               dst128 + 2,     /* b */
    474               dst128 + 1,     /* g */
    475               dst128 + 0,     /* r */
    476               dst128 + 3);    /* a */
    477 
    478          dst128 += 4;
    479          src_row += sizeof(__m128i);
    480       }
    481 
    482       src += 4 * src_stride;
    483    }
    484 }
    485 
    486 static void
    487 lp_tile_b8g8r8x8_unorm_unswizzle_4ub_sse2(const uint8_t * restrict src,
    488                                           uint8_t * restrict dst, unsigned dst_stride,
    489                                           unsigned x0, unsigned y0)
    490 {
    491    unsigned int x, y;
    492    const __m128i *src128 = (const __m128i *) src;
    493 
    494    dst += y0 * dst_stride;
    495    dst += x0 * sizeof(uint32_t);
    496 
    497    for (y = 0; y < TILE_SIZE; y += 4) {
    498       const uint8_t *dst_row = dst;
    499 
    500       for (x = 0; x < TILE_SIZE; x += 4) {
    501          unswz4( &src128[2],     /* b */
    502                  &src128[1],     /* g */
    503                  &src128[0],     /* r */
    504                  &src128[3],     /* a */
    505                  (__m128i *) (dst_row + 0 * dst_stride),
    506                  (__m128i *) (dst_row + 1 * dst_stride),
    507                  (__m128i *) (dst_row + 2 * dst_stride),
    508                  (__m128i *) (dst_row + 3 * dst_stride));
    509 
    510          src128 += 4;
    511          dst_row += sizeof(__m128i);;
    512       }
    513 
    514       dst += 4 * dst_stride;
    515    }
    516 }
    517 
    518 #endif /* PIPE_ARCH_SSE */
    519 '''
    520 
    521 
    522 def generate_swizzle(formats, dst_channel, dst_native_type, dst_suffix):
    523     '''Generate the dispatch function to read pixels from any format'''
    524 
    525     for format in formats:
    526         if is_format_supported(format):
    527             generate_format_read(format, dst_channel, dst_native_type, dst_suffix)
    528 
    529     print 'void'
    530     print 'lp_tile_swizzle_%s(enum pipe_format format, %s *dst, const void *src, unsigned src_stride, unsigned x, unsigned y)' % (dst_suffix, dst_native_type)
    531     print '{'
    532     print '   void (*func)(%s * restrict dst, const uint8_t * restrict src, unsigned src_stride, unsigned x0, unsigned y0);' % dst_native_type
    533     print '#ifdef DEBUG'
    534     print '   lp_tile_swizzle_count += 1;'
    535     print '#endif'
    536     print '   switch(format) {'
    537     for format in formats:
    538         if is_format_supported(format):
    539             print '   case %s:' % format.name
    540             func_name = 'lp_tile_%s_swizzle_%s' % (format.short_name(), dst_suffix)
    541             if format.name == 'PIPE_FORMAT_B8G8R8A8_UNORM' or format.name == 'PIPE_FORMAT_B8G8R8X8_UNORM':
    542                 print '#ifdef PIPE_ARCH_SSE'
    543                 print '      func = util_cpu_caps.has_sse2 ? %s_sse2 : %s;' % (func_name, func_name)
    544                 print '#else'
    545                 print '      func = %s;' % (func_name,)
    546                 print '#endif'
    547             else:
    548                 print '      func = %s;' % (func_name,)
    549             print '      break;'
    550     print '   default:'
    551     print '      debug_printf("%s: unsupported format %s\\n", __FUNCTION__, util_format_name(format));'
    552     print '      return;'
    553     print '   }'
    554     print '   func(dst, (const uint8_t *)src, src_stride, x, y);'
    555     print '}'
    556     print
    557 
    558 
    559 def generate_unswizzle(formats, src_channel, src_native_type, src_suffix):
    560     '''Generate the dispatch function to write pixels to any format'''
    561 
    562     for format in formats:
    563         if is_format_supported(format):
    564             generate_format_write(format, src_channel, src_native_type, src_suffix)
    565 
    566     print 'void'
    567     print 'lp_tile_unswizzle_%s(enum pipe_format format, const %s *src, void *dst, unsigned dst_stride, unsigned x, unsigned y)' % (src_suffix, src_native_type)
    568     
    569     print '{'
    570     print '   void (*func)(const %s * restrict src, uint8_t * restrict dst, unsigned dst_stride, unsigned x0, unsigned y0);' % src_native_type
    571     print '#ifdef DEBUG'
    572     print '   lp_tile_unswizzle_count += 1;'
    573     print '#endif'
    574     print '   switch(format) {'
    575     for format in formats:
    576         if is_format_supported(format):
    577             print '   case %s:' % format.name
    578             func_name = 'lp_tile_%s_unswizzle_%s' % (format.short_name(), src_suffix)
    579             if format.name == 'PIPE_FORMAT_B8G8R8A8_UNORM' or format.name == 'PIPE_FORMAT_B8G8R8X8_UNORM':
    580                 print '#ifdef PIPE_ARCH_SSE'
    581                 print '      func = util_cpu_caps.has_sse2 ? %s_sse2 : %s;' % (func_name, func_name)
    582                 print '#else'
    583                 print '      func = %s;' % (func_name,)
    584                 print '#endif'
    585             else:
    586                 print '      func = %s;' % (func_name,)
    587             print '      break;'
    588     print '   default:'
    589     print '      debug_printf("%s: unsupported format %s\\n", __FUNCTION__, util_format_name(format));'
    590     print '      return;'
    591     print '   }'
    592     print '   func(src, (uint8_t *)dst, dst_stride, x, y);'
    593     print '}'
    594     print
    595 
    596 
    597 def main():
    598     formats = []
    599     for arg in sys.argv[1:]:
    600         formats.extend(parse(arg))
    601 
    602     print '/* This file is autogenerated by lp_tile_soa.py from u_format.csv. Do not edit directly. */'
    603     print
    604     # This will print the copyright message on the top of this file
    605     print CopyRight.strip()
    606     print
    607     print '#include "pipe/p_compiler.h"'
    608     print '#include "util/u_math.h"'
    609     print '#include "util/u_format.h"'
    610     print '#include "util/u_format_r11g11b10f.h"'
    611     print '#include "util/u_format_rgb9e5.h"'
    612     print '#include "util/u_half.h"'
    613     print '#include "util/u_cpu_detect.h"'
    614     print '#include "lp_tile_soa.h"'
    615     print
    616     print '#ifdef DEBUG'
    617     print 'unsigned lp_tile_unswizzle_count = 0;'
    618     print 'unsigned lp_tile_swizzle_count = 0;'
    619     print '#endif'
    620     print
    621     print 'const unsigned char'
    622     print 'tile_offset[TILE_VECTOR_HEIGHT][TILE_VECTOR_WIDTH] = {'
    623     print '   {  0,  1,  4,  5},'
    624     print '   {  2,  3,  6,  7},'
    625     print '   {  8,  9, 12, 13},'
    626     print '   { 10, 11, 14, 15}'
    627     print '};'
    628     print
    629     print '/* Note: these lookup tables could be replaced with some'
    630     print ' * bit-twiddling code, but this is a little faster.'
    631     print ' */'
    632     print 'static unsigned tile_x_offset[TILE_VECTOR_WIDTH * TILE_VECTOR_HEIGHT] = {'
    633     print '   0, 1, 0, 1, 2, 3, 2, 3,'
    634     print '   0, 1, 0, 1, 2, 3, 2, 3'
    635     print '};'
    636     print
    637     print 'static unsigned tile_y_offset[TILE_VECTOR_WIDTH * TILE_VECTOR_HEIGHT] = {'
    638     print '   0, 0, 1, 1, 0, 0, 1, 1,'
    639     print '   2, 2, 3, 3, 2, 2, 3, 3'
    640     print '};'
    641     print
    642 
    643     generate_sse2()
    644 
    645     channel = Channel(UNSIGNED, True, False, 8)
    646     native_type = 'uint8_t'
    647     suffix = '4ub'
    648 
    649     generate_swizzle(formats, channel, native_type, suffix)
    650     generate_unswizzle(formats, channel, native_type, suffix)
    651 
    652 
    653 if __name__ == '__main__':
    654     main()
    655