Home | History | Annotate | Download | only in util
      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  * RGBA/float tile get/put functions.
     30  * Usable both by drivers and state trackers.
     31  */
     32 
     33 
     34 #include "pipe/p_defines.h"
     35 #include "util/u_inlines.h"
     36 
     37 #include "util/u_format.h"
     38 #include "util/u_math.h"
     39 #include "util/u_memory.h"
     40 #include "util/u_surface.h"
     41 #include "util/u_tile.h"
     42 
     43 
     44 /**
     45  * Move raw block of pixels from transfer object to user memory.
     46  */
     47 void
     48 pipe_get_tile_raw(struct pipe_transfer *pt,
     49                   const void *src,
     50                   uint x, uint y, uint w, uint h,
     51                   void *dst, int dst_stride)
     52 {
     53    if (dst_stride == 0)
     54       dst_stride = util_format_get_stride(pt->resource->format, w);
     55 
     56    if (u_clip_tile(x, y, &w, &h, &pt->box))
     57       return;
     58 
     59    util_copy_rect(dst, pt->resource->format, dst_stride, 0, 0, w, h, src, pt->stride, x, y);
     60 }
     61 
     62 
     63 /**
     64  * Move raw block of pixels from user memory to transfer object.
     65  */
     66 void
     67 pipe_put_tile_raw(struct pipe_transfer *pt,
     68                   void *dst,
     69                   uint x, uint y, uint w, uint h,
     70                   const void *src, int src_stride)
     71 {
     72    enum pipe_format format = pt->resource->format;
     73 
     74    if (src_stride == 0)
     75       src_stride = util_format_get_stride(format, w);
     76 
     77    if (u_clip_tile(x, y, &w, &h, &pt->box))
     78       return;
     79 
     80    util_copy_rect(dst, format, pt->stride, x, y, w, h, src, src_stride, 0, 0);
     81 }
     82 
     83 
     84 
     85 
     86 /** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */
     87 #define SHORT_TO_FLOAT(S)   ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
     88 
     89 #define UNCLAMPED_FLOAT_TO_SHORT(us, f)  \
     90    us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )
     91 
     92 
     93 
     94 /*** PIPE_FORMAT_Z16_UNORM ***/
     95 
     96 /**
     97  * Return each Z value as four floats in [0,1].
     98  */
     99 static void
    100 z16_get_tile_rgba(const ushort *src,
    101                   unsigned w, unsigned h,
    102                   float *p,
    103                   unsigned dst_stride)
    104 {
    105    const float scale = 1.0f / 65535.0f;
    106    unsigned i, j;
    107 
    108    for (i = 0; i < h; i++) {
    109       float *pRow = p;
    110       for (j = 0; j < w; j++, pRow += 4) {
    111          pRow[0] =
    112          pRow[1] =
    113          pRow[2] =
    114          pRow[3] = *src++ * scale;
    115       }
    116       p += dst_stride;
    117    }
    118 }
    119 
    120 
    121 
    122 
    123 /*** PIPE_FORMAT_Z32_UNORM ***/
    124 
    125 /**
    126  * Return each Z value as four floats in [0,1].
    127  */
    128 static void
    129 z32_get_tile_rgba(const unsigned *src,
    130                   unsigned w, unsigned h,
    131                   float *p,
    132                   unsigned dst_stride)
    133 {
    134    const double scale = 1.0 / (double) 0xffffffff;
    135    unsigned i, j;
    136 
    137    for (i = 0; i < h; i++) {
    138       float *pRow = p;
    139       for (j = 0; j < w; j++, pRow += 4) {
    140          pRow[0] =
    141          pRow[1] =
    142          pRow[2] =
    143          pRow[3] = (float) (*src++ * scale);
    144       }
    145       p += dst_stride;
    146    }
    147 }
    148 
    149 
    150 /*** PIPE_FORMAT_Z24_UNORM_S8_UINT ***/
    151 
    152 /**
    153  * Return Z component as four float in [0,1].  Stencil part ignored.
    154  */
    155 static void
    156 s8z24_get_tile_rgba(const unsigned *src,
    157                     unsigned w, unsigned h,
    158                     float *p,
    159                     unsigned dst_stride)
    160 {
    161    const double scale = 1.0 / ((1 << 24) - 1);
    162    unsigned i, j;
    163 
    164    for (i = 0; i < h; i++) {
    165       float *pRow = p;
    166       for (j = 0; j < w; j++, pRow += 4) {
    167          pRow[0] =
    168          pRow[1] =
    169          pRow[2] =
    170          pRow[3] = (float) (scale * (*src++ & 0xffffff));
    171       }
    172       p += dst_stride;
    173    }
    174 }
    175 
    176 
    177 /*** PIPE_FORMAT_S8_UINT_Z24_UNORM ***/
    178 
    179 /**
    180  * Return Z component as four float in [0,1].  Stencil part ignored.
    181  */
    182 static void
    183 z24s8_get_tile_rgba(const unsigned *src,
    184                     unsigned w, unsigned h,
    185                     float *p,
    186                     unsigned dst_stride)
    187 {
    188    const double scale = 1.0 / ((1 << 24) - 1);
    189    unsigned i, j;
    190 
    191    for (i = 0; i < h; i++) {
    192       float *pRow = p;
    193       for (j = 0; j < w; j++, pRow += 4) {
    194          pRow[0] =
    195          pRow[1] =
    196          pRow[2] =
    197          pRow[3] = (float) (scale * (*src++ >> 8));
    198       }
    199       p += dst_stride;
    200    }
    201 }
    202 
    203 /*** PIPE_FORMAT_S8X24_UINT ***/
    204 
    205 /**
    206  * Return S component as four uint32_t in [0..255].  Z part ignored.
    207  */
    208 static void
    209 s8x24_get_tile_rgba(const unsigned *src,
    210                     unsigned w, unsigned h,
    211                     float *p,
    212                     unsigned dst_stride)
    213 {
    214    unsigned i, j;
    215 
    216    for (i = 0; i < h; i++) {
    217       uint32_t *pRow = (uint32_t *)p;
    218 
    219       for (j = 0; j < w; j++, pRow += 4) {
    220          pRow[0] =
    221          pRow[1] =
    222          pRow[2] =
    223          pRow[3] = ((*src++ >> 24) & 0xff);
    224       }
    225 
    226       p += dst_stride;
    227    }
    228 }
    229 
    230 /*** PIPE_FORMAT_X24S8_UINT ***/
    231 
    232 /**
    233  * Return S component as four uint32_t in [0..255].  Z part ignored.
    234  */
    235 static void
    236 x24s8_get_tile_rgba(const unsigned *src,
    237                     unsigned w, unsigned h,
    238                     float *p,
    239                     unsigned dst_stride)
    240 {
    241    unsigned i, j;
    242 
    243    for (i = 0; i < h; i++) {
    244       uint32_t *pRow = (uint32_t *)p;
    245       for (j = 0; j < w; j++, pRow += 4) {
    246          pRow[0] =
    247          pRow[1] =
    248          pRow[2] =
    249          pRow[3] = (*src++ & 0xff);
    250       }
    251       p += dst_stride;
    252    }
    253 }
    254 
    255 
    256 /**
    257  * Return S component as four uint32_t in [0..255].  Z part ignored.
    258  */
    259 static void
    260 s8_get_tile_rgba(const unsigned char *src,
    261 		 unsigned w, unsigned h,
    262 		 float *p,
    263 		 unsigned dst_stride)
    264 {
    265    unsigned i, j;
    266 
    267    for (i = 0; i < h; i++) {
    268       uint32_t *pRow = (uint32_t *)p;
    269       for (j = 0; j < w; j++, pRow += 4) {
    270          pRow[0] =
    271          pRow[1] =
    272          pRow[2] =
    273          pRow[3] = (*src++ & 0xff);
    274       }
    275       p += dst_stride;
    276    }
    277 }
    278 
    279 /*** PIPE_FORMAT_Z32_FLOAT ***/
    280 
    281 /**
    282  * Return each Z value as four floats in [0,1].
    283  */
    284 static void
    285 z32f_get_tile_rgba(const float *src,
    286                    unsigned w, unsigned h,
    287                    float *p,
    288                    unsigned dst_stride)
    289 {
    290    unsigned i, j;
    291 
    292    for (i = 0; i < h; i++) {
    293       float *pRow = p;
    294       for (j = 0; j < w; j++, pRow += 4) {
    295          pRow[0] =
    296          pRow[1] =
    297          pRow[2] =
    298          pRow[3] = *src++;
    299       }
    300       p += dst_stride;
    301    }
    302 }
    303 
    304 /*** PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ***/
    305 
    306 /**
    307  * Return each Z value as four floats in [0,1].
    308  */
    309 static void
    310 z32f_x24s8_get_tile_rgba(const float *src,
    311                          unsigned w, unsigned h,
    312                          float *p,
    313                          unsigned dst_stride)
    314 {
    315    unsigned i, j;
    316 
    317    for (i = 0; i < h; i++) {
    318       float *pRow = p;
    319       for (j = 0; j < w; j++, pRow += 4) {
    320          pRow[0] =
    321          pRow[1] =
    322          pRow[2] =
    323          pRow[3] = *src;
    324          src += 2;
    325       }
    326       p += dst_stride;
    327    }
    328 }
    329 
    330 /*** PIPE_FORMAT_X32_S8X24_UINT ***/
    331 
    332 /**
    333  * Return S component as four uint32_t in [0..255].  Z part ignored.
    334  */
    335 static void
    336 x32_s8_get_tile_rgba(const unsigned *src,
    337                      unsigned w, unsigned h,
    338                      float *p,
    339                      unsigned dst_stride)
    340 {
    341    unsigned i, j;
    342 
    343    for (i = 0; i < h; i++) {
    344       uint32_t *pRow = (uint32_t *)p;
    345       for (j = 0; j < w; j++, pRow += 4) {
    346          src++;
    347          pRow[0] =
    348          pRow[1] =
    349          pRow[2] =
    350          pRow[3] = (*src++ & 0xff);
    351       }
    352       p += dst_stride;
    353    }
    354 }
    355 
    356 void
    357 pipe_tile_raw_to_rgba(enum pipe_format format,
    358                       const void *src,
    359                       uint w, uint h,
    360                       float *dst, unsigned dst_stride)
    361 {
    362    switch (format) {
    363    case PIPE_FORMAT_Z16_UNORM:
    364       z16_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
    365       break;
    366    case PIPE_FORMAT_Z32_UNORM:
    367       z32_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
    368       break;
    369    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
    370    case PIPE_FORMAT_Z24X8_UNORM:
    371       s8z24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
    372       break;
    373    case PIPE_FORMAT_S8_UINT:
    374       s8_get_tile_rgba((unsigned char *) src, w, h, dst, dst_stride);
    375       break;
    376    case PIPE_FORMAT_X24S8_UINT:
    377       s8x24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
    378       break;
    379    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
    380    case PIPE_FORMAT_X8Z24_UNORM:
    381       z24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
    382       break;
    383    case PIPE_FORMAT_S8X24_UINT:
    384       x24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
    385       break;
    386    case PIPE_FORMAT_Z32_FLOAT:
    387       z32f_get_tile_rgba((float *) src, w, h, dst, dst_stride);
    388       break;
    389    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
    390       z32f_x24s8_get_tile_rgba((float *) src, w, h, dst, dst_stride);
    391       break;
    392    case PIPE_FORMAT_X32_S8X24_UINT:
    393       x32_s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
    394       break;
    395    default:
    396       util_format_read_4f(format,
    397                           dst, dst_stride * sizeof(float),
    398                           src, util_format_get_stride(format, w),
    399                           0, 0, w, h);
    400    }
    401 }
    402 
    403 void
    404 pipe_tile_raw_to_unsigned(enum pipe_format format,
    405                           const void *src,
    406                           uint w, uint h,
    407                           unsigned *dst, unsigned dst_stride)
    408 {
    409   util_format_read_4ui(format,
    410                        dst, dst_stride * sizeof(float),
    411                        src, util_format_get_stride(format, w),
    412                        0, 0, w, h);
    413 }
    414 
    415 void
    416 pipe_tile_raw_to_signed(enum pipe_format format,
    417                           void *src,
    418                           uint w, uint h,
    419                           int *dst, unsigned dst_stride)
    420 {
    421   util_format_read_4i(format,
    422                       dst, dst_stride * sizeof(float),
    423                       src, util_format_get_stride(format, w),
    424                       0, 0, w, h);
    425 }
    426 
    427 void
    428 pipe_get_tile_rgba(struct pipe_transfer *pt,
    429                    const void *src,
    430                    uint x, uint y, uint w, uint h,
    431                    float *p)
    432 {
    433    pipe_get_tile_rgba_format(pt, src, x, y, w, h, pt->resource->format, p);
    434 }
    435 
    436 
    437 void
    438 pipe_get_tile_rgba_format(struct pipe_transfer *pt,
    439                           const void *src,
    440                           uint x, uint y, uint w, uint h,
    441                           enum pipe_format format,
    442                           float *p)
    443 {
    444    unsigned dst_stride = w * 4;
    445    void *packed;
    446 
    447    if (u_clip_tile(x, y, &w, &h, &pt->box)) {
    448       return;
    449    }
    450 
    451    packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
    452    if (!packed) {
    453       return;
    454    }
    455 
    456    if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) {
    457       assert((x & 1) == 0);
    458    }
    459 
    460    pipe_get_tile_raw(pt, src, x, y, w, h, packed, 0);
    461 
    462    pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride);
    463 
    464    FREE(packed);
    465 }
    466 
    467 
    468 void
    469 pipe_put_tile_rgba(struct pipe_transfer *pt,
    470                    void *dst,
    471                    uint x, uint y, uint w, uint h,
    472                    const float *p)
    473 {
    474    pipe_put_tile_rgba_format(pt, dst, x, y, w, h, pt->resource->format, p);
    475 }
    476 
    477 
    478 void
    479 pipe_put_tile_rgba_format(struct pipe_transfer *pt,
    480                           void *dst,
    481                           uint x, uint y, uint w, uint h,
    482                           enum pipe_format format,
    483                           const float *p)
    484 {
    485    unsigned src_stride = w * 4;
    486    void *packed;
    487 
    488    if (u_clip_tile(x, y, &w, &h, &pt->box))
    489       return;
    490 
    491    packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
    492 
    493    if (!packed)
    494       return;
    495 
    496    switch (format) {
    497    case PIPE_FORMAT_Z16_UNORM:
    498       /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
    499       break;
    500    case PIPE_FORMAT_Z32_UNORM:
    501       /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
    502       break;
    503    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
    504    case PIPE_FORMAT_Z24X8_UNORM:
    505       /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
    506       break;
    507    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
    508    case PIPE_FORMAT_X8Z24_UNORM:
    509       /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
    510       break;
    511    case PIPE_FORMAT_Z32_FLOAT:
    512       /*z32f_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
    513       break;
    514    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
    515       /*z32f_s8x24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
    516       break;
    517    default:
    518       util_format_write_4f(format,
    519                            p, src_stride * sizeof(float),
    520                            packed, util_format_get_stride(format, w),
    521                            0, 0, w, h);
    522    }
    523 
    524    pipe_put_tile_raw(pt, dst, x, y, w, h, packed, 0);
    525 
    526    FREE(packed);
    527 }
    528 
    529 void
    530 pipe_put_tile_i_format(struct pipe_transfer *pt,
    531                        void *dst,
    532                        uint x, uint y, uint w, uint h,
    533                        enum pipe_format format,
    534                        const int *p)
    535 {
    536    unsigned src_stride = w * 4;
    537    void *packed;
    538 
    539    if (u_clip_tile(x, y, &w, &h, &pt->box))
    540       return;
    541 
    542    packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
    543 
    544    if (!packed)
    545       return;
    546 
    547    util_format_write_4i(format,
    548                         p, src_stride * sizeof(float),
    549                         packed, util_format_get_stride(format, w),
    550                         0, 0, w, h);
    551 
    552    pipe_put_tile_raw(pt, dst, x, y, w, h, packed, 0);
    553 
    554    FREE(packed);
    555 }
    556 
    557 void
    558 pipe_put_tile_ui_format(struct pipe_transfer *pt,
    559                         void *dst,
    560                         uint x, uint y, uint w, uint h,
    561                         enum pipe_format format,
    562                         const unsigned int *p)
    563 {
    564    unsigned src_stride = w * 4;
    565    void *packed;
    566 
    567    if (u_clip_tile(x, y, &w, &h, &pt->box))
    568       return;
    569 
    570    packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
    571 
    572    if (!packed)
    573       return;
    574 
    575    util_format_write_4ui(format,
    576                          p, src_stride * sizeof(float),
    577                          packed, util_format_get_stride(format, w),
    578                          0, 0, w, h);
    579 
    580    pipe_put_tile_raw(pt, dst, x, y, w, h, packed, 0);
    581 
    582    FREE(packed);
    583 }
    584 
    585 /**
    586  * Get a block of Z values, converted to 32-bit range.
    587  */
    588 void
    589 pipe_get_tile_z(struct pipe_transfer *pt,
    590                 const void *src,
    591                 uint x, uint y, uint w, uint h,
    592                 uint *z)
    593 {
    594    const uint dstStride = w;
    595    const ubyte *map = src;
    596    uint *pDest = z;
    597    uint i, j;
    598    enum pipe_format format = pt->resource->format;
    599 
    600    if (u_clip_tile(x, y, &w, &h, &pt->box))
    601       return;
    602 
    603    switch (format) {
    604    case PIPE_FORMAT_Z32_UNORM:
    605       {
    606          const uint *ptrc
    607             = (const uint *)(map  + y * pt->stride + x*4);
    608          for (i = 0; i < h; i++) {
    609             memcpy(pDest, ptrc, 4 * w);
    610             pDest += dstStride;
    611             ptrc += pt->stride/4;
    612          }
    613       }
    614       break;
    615    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
    616    case PIPE_FORMAT_Z24X8_UNORM:
    617       {
    618          const uint *ptrc
    619             = (const uint *)(map + y * pt->stride + x*4);
    620          for (i = 0; i < h; i++) {
    621             for (j = 0; j < w; j++) {
    622                /* convert 24-bit Z to 32-bit Z */
    623                pDest[j] = (ptrc[j] << 8) | ((ptrc[j] >> 16) & 0xff);
    624             }
    625             pDest += dstStride;
    626             ptrc += pt->stride/4;
    627          }
    628       }
    629       break;
    630    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
    631    case PIPE_FORMAT_X8Z24_UNORM:
    632       {
    633          const uint *ptrc
    634             = (const uint *)(map + y * pt->stride + x*4);
    635          for (i = 0; i < h; i++) {
    636             for (j = 0; j < w; j++) {
    637                /* convert 24-bit Z to 32-bit Z */
    638                pDest[j] = (ptrc[j] & 0xffffff00) | ((ptrc[j] >> 24) & 0xff);
    639             }
    640             pDest += dstStride;
    641             ptrc += pt->stride/4;
    642          }
    643       }
    644       break;
    645    case PIPE_FORMAT_Z16_UNORM:
    646       {
    647          const ushort *ptrc
    648             = (const ushort *)(map + y * pt->stride + x*2);
    649          for (i = 0; i < h; i++) {
    650             for (j = 0; j < w; j++) {
    651                /* convert 16-bit Z to 32-bit Z */
    652                pDest[j] = (ptrc[j] << 16) | ptrc[j];
    653             }
    654             pDest += dstStride;
    655             ptrc += pt->stride/2;
    656          }
    657       }
    658       break;
    659    case PIPE_FORMAT_Z32_FLOAT:
    660       {
    661          const float *ptrc = (const float *)(map + y * pt->stride + x*4);
    662          for (i = 0; i < h; i++) {
    663             for (j = 0; j < w; j++) {
    664                /* convert float Z to 32-bit Z */
    665                if (ptrc[j] <= 0.0) {
    666                   pDest[j] = 0;
    667                }
    668                else if (ptrc[j] >= 1.0) {
    669                   pDest[j] = 0xffffffff;
    670                }
    671                else {
    672                   double z = ptrc[j] * 0xffffffff;
    673                   pDest[j] = (uint) z;
    674                }
    675             }
    676             pDest += dstStride;
    677             ptrc += pt->stride/4;
    678          }
    679       }
    680       break;
    681    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
    682       {
    683          const float *ptrc = (const float *)(map + y * pt->stride + x*8);
    684          for (i = 0; i < h; i++) {
    685             for (j = 0; j < w; j++) {
    686                /* convert float Z to 32-bit Z */
    687                if (ptrc[j] <= 0.0) {
    688                   pDest[j*2] = 0;
    689                }
    690                else if (ptrc[j] >= 1.0) {
    691                   pDest[j*2] = 0xffffffff;
    692                }
    693                else {
    694                   double z = ptrc[j] * 0xffffffff;
    695                   pDest[j*2] = (uint) z;
    696                }
    697             }
    698             pDest += dstStride;
    699             ptrc += pt->stride/4;
    700          }
    701       }
    702       break;
    703    default:
    704       assert(0);
    705    }
    706 }
    707 
    708 
    709 void
    710 pipe_put_tile_z(struct pipe_transfer *pt,
    711                 void *dst,
    712                 uint x, uint y, uint w, uint h,
    713                 const uint *zSrc)
    714 {
    715    const uint srcStride = w;
    716    const uint *ptrc = zSrc;
    717    ubyte *map = dst;
    718    uint i, j;
    719    enum pipe_format format = pt->resource->format;
    720 
    721    if (u_clip_tile(x, y, &w, &h, &pt->box))
    722       return;
    723 
    724    switch (format) {
    725    case PIPE_FORMAT_Z32_UNORM:
    726       {
    727          uint *pDest = (uint *) (map + y * pt->stride + x*4);
    728          for (i = 0; i < h; i++) {
    729             memcpy(pDest, ptrc, 4 * w);
    730             pDest += pt->stride/4;
    731             ptrc += srcStride;
    732          }
    733       }
    734       break;
    735    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
    736       {
    737          uint *pDest = (uint *) (map + y * pt->stride + x*4);
    738          /*assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);*/
    739          for (i = 0; i < h; i++) {
    740             for (j = 0; j < w; j++) {
    741                /* convert 32-bit Z to 24-bit Z, preserve stencil */
    742                pDest[j] = (pDest[j] & 0xff000000) | ptrc[j] >> 8;
    743             }
    744             pDest += pt->stride/4;
    745             ptrc += srcStride;
    746          }
    747       }
    748       break;
    749    case PIPE_FORMAT_Z24X8_UNORM:
    750       {
    751          uint *pDest = (uint *) (map + y * pt->stride + x*4);
    752          for (i = 0; i < h; i++) {
    753             for (j = 0; j < w; j++) {
    754                /* convert 32-bit Z to 24-bit Z (0 stencil) */
    755                pDest[j] = ptrc[j] >> 8;
    756             }
    757             pDest += pt->stride/4;
    758             ptrc += srcStride;
    759          }
    760       }
    761       break;
    762    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
    763       {
    764          uint *pDest = (uint *) (map + y * pt->stride + x*4);
    765          /*assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);*/
    766          for (i = 0; i < h; i++) {
    767             for (j = 0; j < w; j++) {
    768                /* convert 32-bit Z to 24-bit Z, preserve stencil */
    769                pDest[j] = (pDest[j] & 0xff) | (ptrc[j] & 0xffffff00);
    770             }
    771             pDest += pt->stride/4;
    772             ptrc += srcStride;
    773          }
    774       }
    775       break;
    776    case PIPE_FORMAT_X8Z24_UNORM:
    777       {
    778          uint *pDest = (uint *) (map + y * pt->stride + x*4);
    779          for (i = 0; i < h; i++) {
    780             for (j = 0; j < w; j++) {
    781                /* convert 32-bit Z to 24-bit Z (0 stencil) */
    782                pDest[j] = ptrc[j] & 0xffffff00;
    783             }
    784             pDest += pt->stride/4;
    785             ptrc += srcStride;
    786          }
    787       }
    788       break;
    789    case PIPE_FORMAT_Z16_UNORM:
    790       {
    791          ushort *pDest = (ushort *) (map + y * pt->stride + x*2);
    792          for (i = 0; i < h; i++) {
    793             for (j = 0; j < w; j++) {
    794                /* convert 32-bit Z to 16-bit Z */
    795                pDest[j] = ptrc[j] >> 16;
    796             }
    797             pDest += pt->stride/2;
    798             ptrc += srcStride;
    799          }
    800       }
    801       break;
    802    case PIPE_FORMAT_Z32_FLOAT:
    803       {
    804          float *pDest = (float *) (map + y * pt->stride + x*4);
    805          for (i = 0; i < h; i++) {
    806             for (j = 0; j < w; j++) {
    807                /* convert 32-bit integer Z to float Z */
    808                const double scale = 1.0 / 0xffffffffU;
    809                pDest[j] = (float) (ptrc[j] * scale);
    810             }
    811             pDest += pt->stride/4;
    812             ptrc += srcStride;
    813          }
    814       }
    815       break;
    816    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
    817       {
    818          float *pDest = (float *) (map + y * pt->stride + x*8);
    819          for (i = 0; i < h; i++) {
    820             for (j = 0; j < w; j++) {
    821                /* convert 32-bit integer Z to float Z */
    822                const double scale = 1.0 / 0xffffffffU;
    823                pDest[j*2] = (float) (ptrc[j] * scale);
    824             }
    825             pDest += pt->stride/4;
    826             ptrc += srcStride;
    827          }
    828       }
    829       break;
    830    default:
    831       assert(0);
    832    }
    833 }
    834 
    835 
    836 void
    837 pipe_get_tile_ui_format(struct pipe_transfer *pt,
    838                         const void *src,
    839                         uint x, uint y, uint w, uint h,
    840                         enum pipe_format format,
    841                         unsigned int *p)
    842 {
    843    unsigned dst_stride = w * 4;
    844    void *packed;
    845 
    846    if (u_clip_tile(x, y, &w, &h, &pt->box)) {
    847       return;
    848    }
    849 
    850    packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
    851    if (!packed) {
    852       return;
    853    }
    854 
    855    if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) {
    856       assert((x & 1) == 0);
    857    }
    858 
    859    pipe_get_tile_raw(pt, src, x, y, w, h, packed, 0);
    860 
    861    pipe_tile_raw_to_unsigned(format, packed, w, h, p, dst_stride);
    862 
    863    FREE(packed);
    864 }
    865 
    866 
    867 void
    868 pipe_get_tile_i_format(struct pipe_transfer *pt,
    869                        const void *src,
    870                        uint x, uint y, uint w, uint h,
    871                        enum pipe_format format,
    872                        int *p)
    873 {
    874    unsigned dst_stride = w * 4;
    875    void *packed;
    876 
    877    if (u_clip_tile(x, y, &w, &h, &pt->box)) {
    878       return;
    879    }
    880 
    881    packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
    882    if (!packed) {
    883       return;
    884    }
    885 
    886    if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) {
    887       assert((x & 1) == 0);
    888    }
    889 
    890    pipe_get_tile_raw(pt, src, x, y, w, h, packed, 0);
    891 
    892    pipe_tile_raw_to_signed(format, packed, w, h, p, dst_stride);
    893 
    894    FREE(packed);
    895 }
    896