u_tile.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  * 
00003  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  * 
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  * 
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  * 
00026  **************************************************************************/
00027 
00035 #include "pipe/p_defines.h"
00036 #include "pipe/p_inlines.h"
00037 
00038 #include "util/u_math.h"
00039 #include "util/u_memory.h"
00040 #include "util/u_rect.h"
00041 #include "util/u_tile.h"
00042 
00043 
00048 void
00049 pipe_get_tile_raw(struct pipe_surface *ps,
00050                   uint x, uint y, uint w, uint h,
00051                   void *dst, int dst_stride)
00052 {
00053    const void *src;
00054 
00055    if (dst_stride == 0)
00056       dst_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size;
00057 
00058    if (pipe_clip_tile(x, y, &w, &h, ps))
00059       return;
00060 
00061    src = pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_READ);
00062    assert(src);
00063    if(!src)
00064       return;
00065 
00066    pipe_copy_rect(dst, &ps->block, dst_stride, 0, 0, w, h, src, ps->stride, x, y);
00067 
00068    pipe_surface_unmap(ps);
00069 }
00070 
00071 
00076 void
00077 pipe_put_tile_raw(struct pipe_surface *ps,
00078                   uint x, uint y, uint w, uint h,
00079                   const void *src, int src_stride)
00080 {
00081    void *dst;
00082 
00083    if (src_stride == 0)
00084       src_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size;
00085 
00086    if (pipe_clip_tile(x, y, &w, &h, ps))
00087       return;
00088 
00089    dst = pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_WRITE);
00090    assert(dst);
00091    if(!dst)
00092       return;
00093 
00094    pipe_copy_rect(dst, &ps->block, ps->stride, x, y, w, h, src, src_stride, 0, 0);
00095 
00096    pipe_surface_unmap(ps);
00097 }
00098 
00099 
00100 
00101 
00103 #define SHORT_TO_FLOAT(S)   ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
00104 
00105 #define UNCLAMPED_FLOAT_TO_SHORT(us, f)  \
00106    us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) )
00107 
00108 
00109 
00110 /*** PIPE_FORMAT_A8R8G8B8_UNORM ***/
00111 
00112 static void
00113 a8r8g8b8_get_tile_rgba(const unsigned *src,
00114                        unsigned w, unsigned h,
00115                        float *p,
00116                        unsigned dst_stride)
00117 {
00118    unsigned i, j;
00119 
00120    for (i = 0; i < h; i++) {
00121       float *pRow = p;
00122       for (j = 0; j < w; j++, pRow += 4) {
00123          const unsigned pixel = *src++;
00124          pRow[0] = ubyte_to_float((pixel >> 16) & 0xff);
00125          pRow[1] = ubyte_to_float((pixel >>  8) & 0xff);
00126          pRow[2] = ubyte_to_float((pixel >>  0) & 0xff);
00127          pRow[3] = ubyte_to_float((pixel >> 24) & 0xff);
00128       }
00129       p += dst_stride;
00130    }
00131 }
00132 
00133 
00134 static void
00135 a8r8g8b8_put_tile_rgba(unsigned *dst,
00136                        unsigned w, unsigned h,
00137                        const float *p,
00138                        unsigned src_stride)
00139 {
00140    unsigned i, j;
00141 
00142    for (i = 0; i < h; i++) {
00143       const float *pRow = p;
00144       for (j = 0; j < w; j++, pRow += 4) {
00145          unsigned r, g, b, a;
00146          r = float_to_ubyte(pRow[0]);
00147          g = float_to_ubyte(pRow[1]);
00148          b = float_to_ubyte(pRow[2]);
00149          a = float_to_ubyte(pRow[3]);
00150          *dst++ = (a << 24) | (r << 16) | (g << 8) | b;
00151       }
00152       p += src_stride;
00153    }
00154 }
00155 
00156 
00157 /*** PIPE_FORMAT_A8R8G8B8_UNORM ***/
00158 
00159 static void
00160 x8r8g8b8_get_tile_rgba(const unsigned *src,
00161                        unsigned w, unsigned h,
00162                        float *p,
00163                        unsigned dst_stride)
00164 {
00165    unsigned i, j;
00166 
00167    for (i = 0; i < h; i++) {
00168       float *pRow = p;
00169       for (j = 0; j < w; j++, pRow += 4) {
00170          const unsigned pixel = *src++;
00171          pRow[0] = ubyte_to_float((pixel >> 16) & 0xff);
00172          pRow[1] = ubyte_to_float((pixel >>  8) & 0xff);
00173          pRow[2] = ubyte_to_float((pixel >>  0) & 0xff);
00174          pRow[3] = ubyte_to_float(0xff);
00175       }
00176       p += dst_stride;
00177    }
00178 }
00179 
00180 
00181 static void
00182 x8r8g8b8_put_tile_rgba(unsigned *dst,
00183                        unsigned w, unsigned h,
00184                        const float *p,
00185                        unsigned src_stride)
00186 {
00187    unsigned i, j;
00188 
00189    for (i = 0; i < h; i++) {
00190       const float *pRow = p;
00191       for (j = 0; j < w; j++, pRow += 4) {
00192          unsigned r, g, b;
00193          r = float_to_ubyte(pRow[0]);
00194          g = float_to_ubyte(pRow[1]);
00195          b = float_to_ubyte(pRow[2]);
00196          *dst++ = (0xff << 24) | (r << 16) | (g << 8) | b;
00197       }
00198       p += src_stride;
00199    }
00200 }
00201 
00202 
00203 /*** PIPE_FORMAT_B8G8R8A8_UNORM ***/
00204 
00205 static void
00206 b8g8r8a8_get_tile_rgba(const unsigned *src,
00207                        unsigned w, unsigned h,
00208                        float *p,
00209                        unsigned dst_stride)
00210 {
00211    unsigned i, j;
00212 
00213    for (i = 0; i < h; i++) {
00214       float *pRow = p;
00215       for (j = 0; j < w; j++, pRow += 4) {
00216          const unsigned pixel = *src++;
00217          pRow[0] = ubyte_to_float((pixel >>  8) & 0xff);
00218          pRow[1] = ubyte_to_float((pixel >> 16) & 0xff);
00219          pRow[2] = ubyte_to_float((pixel >> 24) & 0xff);
00220          pRow[3] = ubyte_to_float((pixel >>  0) & 0xff);
00221       }
00222       p += dst_stride;
00223    }
00224 }
00225 
00226 
00227 static void
00228 b8g8r8a8_put_tile_rgba(unsigned *dst,
00229                        unsigned w, unsigned h,
00230                        const float *p,
00231                        unsigned src_stride)
00232 {
00233    unsigned i, j;
00234 
00235    for (i = 0; i < h; i++) {
00236       const float *pRow = p;
00237       for (j = 0; j < w; j++, pRow += 4) {
00238          unsigned r, g, b, a;
00239          r = float_to_ubyte(pRow[0]);
00240          g = float_to_ubyte(pRow[1]);
00241          b = float_to_ubyte(pRow[2]);
00242          a = float_to_ubyte(pRow[3]);
00243          *dst++ = (b << 24) | (g << 16) | (r << 8) | a;
00244       }
00245       p += src_stride;
00246    }
00247 }
00248 
00249 
00250 /*** PIPE_FORMAT_A1R5G5B5_UNORM ***/
00251 
00252 static void
00253 a1r5g5b5_get_tile_rgba(const ushort *src,
00254                        unsigned w, unsigned h,
00255                        float *p,
00256                        unsigned dst_stride)
00257 {
00258    unsigned i, j;
00259 
00260    for (i = 0; i < h; i++) {
00261       float *pRow = p;
00262       for (j = 0; j < w; j++, pRow += 4) {
00263          const ushort pixel = *src++;
00264          pRow[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f);
00265          pRow[1] = ((pixel >>  5) & 0x1f) * (1.0f / 31.0f);
00266          pRow[2] = ((pixel      ) & 0x1f) * (1.0f / 31.0f);
00267          pRow[3] = ((pixel >> 15)       ) * 1.0f;
00268       }
00269       p += dst_stride;
00270    }
00271 }
00272 
00273 
00274 static void
00275 a1r5g5b5_put_tile_rgba(ushort *dst,
00276                        unsigned w, unsigned h,
00277                        const float *p,
00278                        unsigned src_stride)
00279 {
00280    unsigned i, j;
00281 
00282    for (i = 0; i < h; i++) {
00283       const float *pRow = p;
00284       for (j = 0; j < w; j++, pRow += 4) {
00285          unsigned r, g, b, a;
00286          r = float_to_ubyte(pRow[0]);
00287          g = float_to_ubyte(pRow[1]);
00288          b = float_to_ubyte(pRow[2]);
00289          a = float_to_ubyte(pRow[3]);
00290          r = r >> 3;  /* 5 bits */
00291          g = g >> 3;  /* 5 bits */
00292          b = b >> 3;  /* 5 bits */
00293          a = a >> 7;  /* 1 bit */
00294          *dst++ = (a << 15) | (r << 10) | (g << 5) | b;
00295       }
00296       p += src_stride;
00297    }
00298 }
00299 
00300 
00301 /*** PIPE_FORMAT_A4R4G4B4_UNORM ***/
00302 
00303 static void
00304 a4r4g4b4_get_tile_rgba(const ushort *src,
00305                        unsigned w, unsigned h,
00306                        float *p,
00307                        unsigned dst_stride)
00308 {
00309    unsigned i, j;
00310 
00311    for (i = 0; i < h; i++) {
00312       float *pRow = p;
00313       for (j = 0; j < w; j++, pRow += 4) {
00314          const ushort pixel = *src++;
00315          pRow[0] = ((pixel >>  8) & 0xf) * (1.0f / 15.0f);
00316          pRow[1] = ((pixel >>  4) & 0xf) * (1.0f / 15.0f);
00317          pRow[2] = ((pixel      ) & 0xf) * (1.0f / 15.0f);
00318          pRow[3] = ((pixel >> 12)      ) * (1.0f / 15.0f);
00319       }
00320       p += dst_stride;
00321    }
00322 }
00323 
00324 
00325 static void
00326 a4r4g4b4_put_tile_rgba(ushort *dst,
00327                        unsigned w, unsigned h,
00328                        const float *p,
00329                        unsigned src_stride)
00330 {
00331    unsigned i, j;
00332 
00333    for (i = 0; i < h; i++) {
00334       const float *pRow = p;
00335       for (j = 0; j < w; j++, pRow += 4) {
00336          unsigned r, g, b, a;
00337          r = float_to_ubyte(pRow[0]);
00338          g = float_to_ubyte(pRow[1]);
00339          b = float_to_ubyte(pRow[2]);
00340          a = float_to_ubyte(pRow[3]);
00341          r >>= 4;
00342          g >>= 4;
00343          b >>= 4;
00344          a >>= 4;
00345          *dst++ = (a << 12) | (r << 16) | (g << 4) | b;
00346       }
00347       p += src_stride;
00348    }
00349 }
00350 
00351 
00352 /*** PIPE_FORMAT_R5G6B5_UNORM ***/
00353 
00354 static void
00355 r5g6b5_get_tile_rgba(const ushort *src,
00356                      unsigned w, unsigned h,
00357                      float *p,
00358                      unsigned dst_stride)
00359 {
00360    unsigned i, j;
00361 
00362    for (i = 0; i < h; i++) {
00363       float *pRow = p;
00364       for (j = 0; j < w; j++, pRow += 4) {
00365          const ushort pixel = *src++;
00366          pRow[0] = ((pixel >> 11) & 0x1f) * (1.0f / 31.0f);
00367          pRow[1] = ((pixel >>  5) & 0x3f) * (1.0f / 63.0f);
00368          pRow[2] = ((pixel      ) & 0x1f) * (1.0f / 31.0f);
00369          pRow[3] = 1.0f;
00370       }
00371       p += dst_stride;
00372    }
00373 }
00374 
00375 
00376 static void
00377 r5g6b5_put_tile_rgba(ushort *dst,
00378                      unsigned w, unsigned h,
00379                      const float *p,
00380                      unsigned src_stride)
00381 {
00382    unsigned i, j;
00383 
00384    for (i = 0; i < h; i++) {
00385       const float *pRow = p;
00386       for (j = 0; j < w; j++, pRow += 4) {
00387          uint r = (uint) (CLAMP(pRow[0], 0.0, 1.0) * 31.0);
00388          uint g = (uint) (CLAMP(pRow[1], 0.0, 1.0) * 63.0);
00389          uint b = (uint) (CLAMP(pRow[2], 0.0, 1.0) * 31.0);
00390          *dst++ = (r << 11) | (g << 5) | (b);
00391       }
00392       p += src_stride;
00393    }
00394 }
00395 
00396 
00397 
00398 /*** PIPE_FORMAT_Z16_UNORM ***/
00399 
00403 static void
00404 z16_get_tile_rgba(const ushort *src,
00405                   unsigned w, unsigned h,
00406                   float *p,
00407                   unsigned dst_stride)
00408 {
00409    const float scale = 1.0f / 65535.0f;
00410    unsigned i, j;
00411 
00412    for (i = 0; i < h; i++) {
00413       float *pRow = p;
00414       for (j = 0; j < w; j++, pRow += 4) {
00415          pRow[0] =
00416          pRow[1] =
00417          pRow[2] =
00418          pRow[3] = *src++ * scale;
00419       }
00420       p += dst_stride;
00421    }
00422 }
00423 
00424 
00425 
00426 
00427 /*** PIPE_FORMAT_L8_UNORM ***/
00428 
00429 static void
00430 l8_get_tile_rgba(const ubyte *src,
00431                  unsigned w, unsigned h,
00432                  float *p,
00433                  unsigned dst_stride)
00434 {
00435    unsigned i, j;
00436 
00437    for (i = 0; i < h; i++) {
00438       float *pRow = p;
00439       for (j = 0; j < w; j++, src++, pRow += 4) {
00440          pRow[0] =
00441          pRow[1] =
00442          pRow[2] = ubyte_to_float(*src);
00443          pRow[3] = 1.0;
00444       }
00445       p += dst_stride;
00446    }
00447 }
00448 
00449 
00450 static void
00451 l8_put_tile_rgba(ubyte *dst,
00452                  unsigned w, unsigned h,
00453                  const float *p,
00454                  unsigned src_stride)
00455 {
00456    unsigned i, j;
00457 
00458    for (i = 0; i < h; i++) {
00459       const float *pRow = p;
00460       for (j = 0; j < w; j++, pRow += 4) {
00461          unsigned r;
00462          r = float_to_ubyte(pRow[0]);
00463          *dst++ = r;
00464       }
00465       p += src_stride;
00466    }
00467 }
00468 
00469 
00470 
00471 /*** PIPE_FORMAT_A8_UNORM ***/
00472 
00473 static void
00474 a8_get_tile_rgba(const ubyte *src,
00475                  unsigned w, unsigned h,
00476                  float *p,
00477                  unsigned dst_stride)
00478 {
00479    unsigned i, j;
00480 
00481    for (i = 0; i < h; i++) {
00482       float *pRow = p;
00483       for (j = 0; j < w; j++, src++, pRow += 4) {
00484          pRow[0] =
00485          pRow[1] =
00486          pRow[2] = 0.0;
00487          pRow[3] = ubyte_to_float(*src);
00488       }
00489       p += dst_stride;
00490    }
00491 }
00492 
00493 
00494 static void
00495 a8_put_tile_rgba(ubyte *dst,
00496                  unsigned w, unsigned h,
00497                  const float *p,
00498                  unsigned src_stride)
00499 {
00500    unsigned i, j;
00501 
00502    for (i = 0; i < h; i++) {
00503       const float *pRow = p;
00504       for (j = 0; j < w; j++, pRow += 4) {
00505          unsigned a;
00506          a = float_to_ubyte(pRow[3]);
00507          *dst++ = a;
00508       }
00509       p += src_stride;
00510    }
00511 }
00512 
00513 
00514 
00515 /*** PIPE_FORMAT_R16_SNORM ***/
00516 
00517 static void
00518 r16_get_tile_rgba(const short *src,
00519                   unsigned w, unsigned h,
00520                   float *p,
00521                   unsigned dst_stride)
00522 {
00523    unsigned i, j;
00524 
00525    for (i = 0; i < h; i++) {
00526       float *pRow = p;
00527       for (j = 0; j < w; j++, src++, pRow += 4) {
00528          pRow[0] = SHORT_TO_FLOAT(src[0]);
00529          pRow[1] =
00530          pRow[2] = 0.0;
00531          pRow[3] = 1.0;
00532       }
00533       p += dst_stride;
00534    }
00535 }
00536 
00537 
00538 static void
00539 r16_put_tile_rgba(short *dst,
00540                   unsigned w, unsigned h,
00541                   const float *p,
00542                   unsigned src_stride)
00543 {
00544    unsigned i, j;
00545 
00546    for (i = 0; i < h; i++) {
00547       const float *pRow = p;
00548       for (j = 0; j < w; j++, dst++, pRow += 4) {
00549          UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]);
00550       }
00551       p += src_stride;
00552    }
00553 }
00554 
00555 
00556 /*** PIPE_FORMAT_R16G16B16A16_SNORM ***/
00557 
00558 static void
00559 r16g16b16a16_get_tile_rgba(const short *src,
00560                            unsigned w, unsigned h,
00561                            float *p,
00562                            unsigned dst_stride)
00563 {
00564    unsigned i, j;
00565 
00566    for (i = 0; i < h; i++) {
00567       float *pRow = p;
00568       for (j = 0; j < w; j++, src += 4, pRow += 4) {
00569          pRow[0] = SHORT_TO_FLOAT(src[0]);
00570          pRow[1] = SHORT_TO_FLOAT(src[1]);
00571          pRow[2] = SHORT_TO_FLOAT(src[2]);
00572          pRow[3] = SHORT_TO_FLOAT(src[3]);
00573       }
00574       p += dst_stride;
00575    }
00576 }
00577 
00578 
00579 static void
00580 r16g16b16a16_put_tile_rgba(short *dst,
00581                            unsigned w, unsigned h,
00582                            const float *p,
00583                            unsigned src_stride)
00584 {
00585    unsigned i, j;
00586 
00587    for (i = 0; i < h; i++) {
00588       const float *pRow = p;
00589       for (j = 0; j < w; j++, dst += 4, pRow += 4) {
00590          UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]);
00591          UNCLAMPED_FLOAT_TO_SHORT(dst[1], pRow[1]);
00592          UNCLAMPED_FLOAT_TO_SHORT(dst[2], pRow[2]);
00593          UNCLAMPED_FLOAT_TO_SHORT(dst[3], pRow[3]);
00594       }
00595       p += src_stride;
00596    }
00597 }
00598 
00599 
00600 
00601 /*** PIPE_FORMAT_I8_UNORM ***/
00602 
00603 static void
00604 i8_get_tile_rgba(const ubyte *src,
00605                  unsigned w, unsigned h,
00606                  float *p,
00607                  unsigned dst_stride)
00608 {
00609    unsigned i, j;
00610 
00611    for (i = 0; i < h; i++) {
00612       float *pRow = p;
00613       for (j = 0; j < w; j++, src++, pRow += 4) {
00614          pRow[0] =
00615          pRow[1] =
00616          pRow[2] =
00617          pRow[3] = ubyte_to_float(*src);
00618       }
00619       p += dst_stride;
00620    }
00621 }
00622 
00623 
00624 static void
00625 i8_put_tile_rgba(ubyte *dst,
00626                  unsigned w, unsigned h,
00627                  const float *p,
00628                  unsigned src_stride)
00629 {
00630    unsigned i, j;
00631 
00632    for (i = 0; i < h; i++) {
00633       const float *pRow = p;
00634       for (j = 0; j < w; j++, pRow += 4) {
00635          unsigned r;
00636          r = float_to_ubyte(pRow[0]);
00637          *dst++ = r;
00638       }
00639       p += src_stride;
00640    }
00641 }
00642 
00643 
00644 /*** PIPE_FORMAT_A8L8_UNORM ***/
00645 
00646 static void
00647 a8l8_get_tile_rgba(const ushort *src,
00648                    unsigned w, unsigned h,
00649                    float *p,
00650                    unsigned dst_stride)
00651 {
00652    unsigned i, j;
00653 
00654    for (i = 0; i < h; i++) {
00655       float *pRow = p;
00656       for (j = 0; j < w; j++, pRow += 4) {
00657          ushort p = *src++;
00658          pRow[0] =
00659          pRow[1] =
00660          pRow[2] = ubyte_to_float(p & 0xff);
00661          pRow[3] = ubyte_to_float(p >> 8);
00662       }
00663       p += dst_stride;
00664    }
00665 }
00666 
00667 
00668 static void
00669 a8l8_put_tile_rgba(ushort *dst,
00670                    unsigned w, unsigned h,
00671                    const float *p,
00672                    unsigned src_stride)
00673 {
00674    unsigned i, j;
00675 
00676    for (i = 0; i < h; i++) {
00677       const float *pRow = p;
00678       for (j = 0; j < w; j++, pRow += 4) {
00679          unsigned r, a;
00680          r = float_to_ubyte(pRow[0]);
00681          a = float_to_ubyte(pRow[3]);
00682          *dst++ = (a << 8) | r;
00683       }
00684       p += src_stride;
00685    }
00686 }
00687 
00688 
00689 
00690 
00691 /*** PIPE_FORMAT_Z32_UNORM ***/
00692 
00696 static void
00697 z32_get_tile_rgba(const unsigned *src,
00698                   unsigned w, unsigned h,
00699                   float *p,
00700                   unsigned dst_stride)
00701 {
00702    const double scale = 1.0 / (double) 0xffffffff;
00703    unsigned i, j;
00704 
00705    for (i = 0; i < h; i++) {
00706       float *pRow = p;
00707       for (j = 0; j < w; j++, pRow += 4) {
00708          pRow[0] =
00709          pRow[1] =
00710          pRow[2] =
00711          pRow[3] = (float) (*src++ * scale);
00712       }
00713       p += dst_stride;
00714    }
00715 }
00716 
00717 
00718 /*** PIPE_FORMAT_S8Z24_UNORM ***/
00719 
00723 static void
00724 s8z24_get_tile_rgba(const unsigned *src,
00725                     unsigned w, unsigned h,
00726                     float *p,
00727                     unsigned dst_stride)
00728 {
00729    const double scale = 1.0 / ((1 << 24) - 1);
00730    unsigned i, j;
00731 
00732    for (i = 0; i < h; i++) {
00733       float *pRow = p;
00734       for (j = 0; j < w; j++, pRow += 4) {
00735          pRow[0] =
00736          pRow[1] =
00737          pRow[2] =
00738          pRow[3] = (float) (scale * (*src++ & 0xffffff));
00739       }
00740       p += dst_stride;
00741    }
00742 }
00743 
00744 
00745 /*** PIPE_FORMAT_Z24S8_UNORM ***/
00746 
00750 static void
00751 z24s8_get_tile_rgba(const unsigned *src,
00752                     unsigned w, unsigned h,
00753                     float *p,
00754                     unsigned dst_stride)
00755 {
00756    const double scale = 1.0 / ((1 << 24) - 1);
00757    unsigned i, j;
00758 
00759    for (i = 0; i < h; i++) {
00760       float *pRow = p;
00761       for (j = 0; j < w; j++, pRow += 4) {
00762          pRow[0] =
00763          pRow[1] =
00764          pRow[2] =
00765          pRow[3] = (float) (scale * (*src++ >> 8));
00766       }
00767       p += dst_stride;
00768    }
00769 }
00770 
00771 
00772 /*** PIPE_FORMAT_Z32_FLOAT ***/
00773 
00777 static void
00778 z32f_get_tile_rgba(const float *src,
00779                    unsigned w, unsigned h,
00780                    float *p,
00781                    unsigned dst_stride)
00782 {
00783    unsigned i, j;
00784 
00785    for (i = 0; i < h; i++) {
00786       float *pRow = p;
00787       for (j = 0; j < w; j++, pRow += 4) {
00788          pRow[0] =
00789          pRow[1] =
00790          pRow[2] =
00791          pRow[3] = *src++;
00792       }
00793       p += dst_stride;
00794    }
00795 }
00796 
00797 
00798 /*** PIPE_FORMAT_YCBCR / PIPE_FORMAT_YCBCR_REV ***/
00799 
00803 static void
00804 ycbcr_get_tile_rgba(const ushort *src,
00805                     unsigned w, unsigned h,
00806                     float *p,
00807                     unsigned dst_stride,
00808                     boolean rev)
00809 {
00810    const float scale = 1.0f / 255.0f;
00811    unsigned i, j;
00812 
00813    for (i = 0; i < h; i++) {
00814       float *pRow = p;
00815       /* do two texels at a time */
00816       for (j = 0; j < (w & ~1); j += 2, src += 2) {
00817          const ushort t0 = src[0];
00818          const ushort t1 = src[1];
00819          const ubyte y0 = (t0 >> 8) & 0xff;  /* luminance */
00820          const ubyte y1 = (t1 >> 8) & 0xff;  /* luminance */
00821          ubyte cb, cr;
00822          float r, g, b;
00823 
00824          if (rev) {
00825             cb = t1 & 0xff;         /* chroma U */
00826             cr = t0 & 0xff;         /* chroma V */
00827          }
00828          else {
00829             cb = t0 & 0xff;         /* chroma U */
00830             cr = t1 & 0xff;         /* chroma V */
00831          }
00832 
00833          /* even pixel: y0,cr,cb */
00834          r = 1.164f * (y0-16) + 1.596f * (cr-128);
00835          g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
00836          b = 1.164f * (y0-16) + 2.018f * (cb-128);
00837          pRow[0] = r * scale;
00838          pRow[1] = g * scale;
00839          pRow[2] = b * scale;
00840          pRow[3] = 1.0f;
00841          pRow += 4;
00842 
00843          /* odd pixel: use y1,cr,cb */
00844          r = 1.164f * (y1-16) + 1.596f * (cr-128);
00845          g = 1.164f * (y1-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
00846          b = 1.164f * (y1-16) + 2.018f * (cb-128);
00847          pRow[0] = r * scale;
00848          pRow[1] = g * scale;
00849          pRow[2] = b * scale;
00850          pRow[3] = 1.0f;
00851          pRow += 4;
00852 
00853       }
00854       /* do the last texel */
00855       if (w & 1) {
00856          const ushort t0 = src[0];
00857          const ushort t1 = src[1];
00858          const ubyte y0 = (t0 >> 8) & 0xff;  /* luminance */
00859          ubyte cb, cr;
00860          float r, g, b;
00861 
00862          if (rev) {
00863             cb = t1 & 0xff;         /* chroma U */
00864             cr = t0 & 0xff;         /* chroma V */
00865          }
00866          else {
00867             cb = t0 & 0xff;         /* chroma U */
00868             cr = t1 & 0xff;         /* chroma V */
00869          }
00870 
00871          /* even pixel: y0,cr,cb */
00872          r = 1.164f * (y0-16) + 1.596f * (cr-128);
00873          g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
00874          b = 1.164f * (y0-16) + 2.018f * (cb-128);
00875          pRow[0] = r * scale;
00876          pRow[1] = g * scale;
00877          pRow[2] = b * scale;
00878          pRow[3] = 1.0f;
00879          pRow += 4;
00880       }
00881       p += dst_stride;
00882    }
00883 }
00884 
00885 
00886 static void
00887 fake_get_tile_rgba(const ushort *src,
00888                    unsigned w, unsigned h,
00889                    float *p,
00890                    unsigned dst_stride)
00891 {
00892    unsigned i, j;
00893 
00894    for (i = 0; i < h; i++) {
00895       float *pRow = p;
00896       for (j = 0; j < w; j++, pRow += 4) {
00897          pRow[0] =
00898          pRow[1] =
00899          pRow[2] =
00900          pRow[3] = (i ^ j) & 1 ? 1.0f : 0.0f;
00901       }
00902       p += dst_stride;
00903    }
00904 }
00905 
00906 
00907 void
00908 pipe_tile_raw_to_rgba(enum pipe_format format,
00909                       void *src,
00910                       uint w, uint h,
00911                       float *dst, unsigned dst_stride)
00912 {
00913    switch (format) {
00914    case PIPE_FORMAT_A8R8G8B8_UNORM:
00915       a8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
00916       break;
00917    case PIPE_FORMAT_X8R8G8B8_UNORM:
00918       x8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
00919       break;
00920    case PIPE_FORMAT_B8G8R8A8_UNORM:
00921       b8g8r8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
00922       break;
00923    case PIPE_FORMAT_A1R5G5B5_UNORM:
00924       a1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
00925       break;
00926    case PIPE_FORMAT_A4R4G4B4_UNORM:
00927       a4r4g4b4_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
00928       break;
00929    case PIPE_FORMAT_R5G6B5_UNORM:
00930       r5g6b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
00931       break;
00932    case PIPE_FORMAT_L8_UNORM:
00933       l8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
00934       break;
00935    case PIPE_FORMAT_A8_UNORM:
00936       a8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
00937       break;
00938    case PIPE_FORMAT_I8_UNORM:
00939       i8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
00940       break;
00941    case PIPE_FORMAT_A8L8_UNORM:
00942       a8l8_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
00943       break;
00944    case PIPE_FORMAT_R16_SNORM:
00945       r16_get_tile_rgba((short *) src, w, h, dst, dst_stride);
00946       break;
00947    case PIPE_FORMAT_R16G16B16A16_SNORM:
00948       r16g16b16a16_get_tile_rgba((short *) src, w, h, dst, dst_stride);
00949       break;
00950    case PIPE_FORMAT_Z16_UNORM:
00951       z16_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
00952       break;
00953    case PIPE_FORMAT_Z32_UNORM:
00954       z32_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
00955       break;
00956    case PIPE_FORMAT_S8Z24_UNORM:
00957    case PIPE_FORMAT_X8Z24_UNORM:
00958       s8z24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
00959       break;
00960    case PIPE_FORMAT_Z24S8_UNORM:
00961       z24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
00962       break;
00963    case PIPE_FORMAT_Z32_FLOAT:
00964       z32f_get_tile_rgba((float *) src, w, h, dst, dst_stride);
00965       break;
00966    case PIPE_FORMAT_YCBCR:
00967       ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, FALSE);
00968       break;
00969    case PIPE_FORMAT_YCBCR_REV:
00970       ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, TRUE);
00971       break;
00972    default:
00973       debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(format));
00974       fake_get_tile_rgba(src, w, h, dst, dst_stride);
00975    }
00976 }
00977 
00978 
00979 void
00980 pipe_get_tile_rgba(struct pipe_surface *ps,
00981                    uint x, uint y, uint w, uint h,
00982                    float *p)
00983 {
00984    unsigned dst_stride = w * 4;
00985    void *packed;
00986 
00987    if (pipe_clip_tile(x, y, &w, &h, ps))
00988       return;
00989 
00990    packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size);
00991 
00992    if (!packed)
00993       return;
00994 
00995    if(ps->format == PIPE_FORMAT_YCBCR || ps->format == PIPE_FORMAT_YCBCR_REV)
00996       assert((x & 1) == 0);
00997 
00998    pipe_get_tile_raw(ps, x, y, w, h, packed, 0);
00999 
01000    pipe_tile_raw_to_rgba(ps->format, packed, w, h, p, dst_stride);
01001 
01002    FREE(packed);
01003 }
01004 
01005 
01006 void
01007 pipe_put_tile_rgba(struct pipe_surface *ps,
01008                    uint x, uint y, uint w, uint h,
01009                    const float *p)
01010 {
01011    unsigned src_stride = w * 4;
01012    void *packed;
01013 
01014    if (pipe_clip_tile(x, y, &w, &h, ps))
01015       return;
01016 
01017    packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size);
01018 
01019    if (!packed)
01020       return;
01021 
01022    switch (ps->format) {
01023    case PIPE_FORMAT_A8R8G8B8_UNORM:
01024       a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
01025       break;
01026    case PIPE_FORMAT_X8R8G8B8_UNORM:
01027       x8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
01028       break;
01029    case PIPE_FORMAT_B8G8R8A8_UNORM:
01030       b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
01031       break;
01032    case PIPE_FORMAT_A1R5G5B5_UNORM:
01033       a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
01034       break;
01035    case PIPE_FORMAT_R5G6B5_UNORM:
01036       r5g6b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
01037       break;
01038    case PIPE_FORMAT_R8G8B8A8_UNORM:
01039       assert(0);
01040       break;
01041    case PIPE_FORMAT_A4R4G4B4_UNORM:
01042       a4r4g4b4_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
01043       break;
01044    case PIPE_FORMAT_L8_UNORM:
01045       l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
01046       break;
01047    case PIPE_FORMAT_A8_UNORM:
01048       a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
01049       break;
01050    case PIPE_FORMAT_I8_UNORM:
01051       i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
01052       break;
01053    case PIPE_FORMAT_A8L8_UNORM:
01054       a8l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
01055       break;
01056    case PIPE_FORMAT_R16_SNORM:
01057       r16_put_tile_rgba((short *) packed, w, h, p, src_stride);
01058       break;
01059    case PIPE_FORMAT_R16G16B16A16_SNORM:
01060       r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride);
01061       break;
01062    case PIPE_FORMAT_Z16_UNORM:
01063       /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
01064       break;
01065    case PIPE_FORMAT_Z32_UNORM:
01066       /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
01067       break;
01068    case PIPE_FORMAT_S8Z24_UNORM:
01069    case PIPE_FORMAT_X8Z24_UNORM:
01070       /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
01071       break;
01072    case PIPE_FORMAT_Z24S8_UNORM:
01073       /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
01074       break;
01075    default:
01076       debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(ps->format));
01077    }
01078 
01079    pipe_put_tile_raw(ps, x, y, w, h, packed, 0);
01080 
01081    FREE(packed);
01082 }
01083 
01084 
01088 void
01089 pipe_get_tile_z(struct pipe_surface *ps,
01090                 uint x, uint y, uint w, uint h,
01091                 uint *z)
01092 {
01093    const uint dstStride = w;
01094    ubyte *map;
01095    uint *pDest = z;
01096    uint i, j;
01097 
01098    if (pipe_clip_tile(x, y, &w, &h, ps))
01099       return;
01100 
01101    map = (ubyte *)pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_READ);
01102    if (!map) {
01103       assert(0);
01104       return;
01105    }
01106 
01107    switch (ps->format) {
01108    case PIPE_FORMAT_Z32_UNORM:
01109       {
01110          const uint *pSrc
01111             = (const uint *)(map  + y * ps->stride + x*4);
01112          for (i = 0; i < h; i++) {
01113             memcpy(pDest, pSrc, 4 * w);
01114             pDest += dstStride;
01115             pSrc += ps->stride/4;
01116          }
01117       }
01118       break;
01119    case PIPE_FORMAT_S8Z24_UNORM:
01120    case PIPE_FORMAT_X8Z24_UNORM:
01121       {
01122          const uint *pSrc
01123             = (const uint *)(map + y * ps->stride + x*4);
01124          for (i = 0; i < h; i++) {
01125             for (j = 0; j < w; j++) {
01126                /* convert 24-bit Z to 32-bit Z */
01127                pDest[j] = (pSrc[j] << 8) | (pSrc[j] & 0xff);
01128             }
01129             pDest += dstStride;
01130             pSrc += ps->stride/4;
01131          }
01132       }
01133       break;
01134    case PIPE_FORMAT_Z16_UNORM:
01135       {
01136          const ushort *pSrc
01137             = (const ushort *)(map + y * ps->stride + x*2);
01138          for (i = 0; i < h; i++) {
01139             for (j = 0; j < w; j++) {
01140                /* convert 16-bit Z to 32-bit Z */
01141                pDest[j] = (pSrc[j] << 16) | pSrc[j];
01142             }
01143             pDest += dstStride;
01144             pSrc += ps->stride/2;
01145          }
01146       }
01147       break;
01148    default:
01149       assert(0);
01150    }
01151 
01152    pipe_surface_unmap(ps);
01153 }
01154 
01155 
01156 void
01157 pipe_put_tile_z(struct pipe_surface *ps,
01158                 uint x, uint y, uint w, uint h,
01159                 const uint *zSrc)
01160 {
01161    const uint srcStride = w;
01162    const uint *pSrc = zSrc;
01163    ubyte *map;
01164    uint i, j;
01165 
01166    if (pipe_clip_tile(x, y, &w, &h, ps))
01167       return;
01168 
01169    map = (ubyte *)pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_WRITE);
01170    if (!map) {
01171       assert(0);
01172       return;
01173    }
01174 
01175    switch (ps->format) {
01176    case PIPE_FORMAT_Z32_UNORM:
01177       {
01178          uint *pDest = (uint *) (map + y * ps->stride + x*4);
01179          for (i = 0; i < h; i++) {
01180             memcpy(pDest, pSrc, 4 * w);
01181             pDest += ps->stride/4;
01182             pSrc += srcStride;
01183          }
01184       }
01185       break;
01186    case PIPE_FORMAT_S8Z24_UNORM:
01187    case PIPE_FORMAT_X8Z24_UNORM:
01188       {
01189          uint *pDest = (uint *) (map + y * ps->stride + x*4);
01190          for (i = 0; i < h; i++) {
01191             for (j = 0; j < w; j++) {
01192                /* convert 32-bit Z to 24-bit Z (0 stencil) */
01193                pDest[j] = pSrc[j] >> 8;
01194             }
01195             pDest += ps->stride/4;
01196             pSrc += srcStride;
01197          }
01198       }
01199       break;
01200    case PIPE_FORMAT_Z16_UNORM:
01201       {
01202          ushort *pDest = (ushort *) (map + y * ps->stride + x*2);
01203          for (i = 0; i < h; i++) {
01204             for (j = 0; j < w; j++) {
01205                /* convert 32-bit Z to 16-bit Z */
01206                pDest[j] = pSrc[j] >> 16;
01207             }
01208             pDest += ps->stride/2;
01209             pSrc += srcStride;
01210          }
01211       }
01212       break;
01213    default:
01214       assert(0);
01215    }
01216 
01217    pipe_surface_unmap(ps);
01218 }
01219 
01220 

Generated on Tue Sep 29 06:25:15 2009 for Gallium3D by  doxygen 1.5.4