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