Home | History | Annotate | Download | only in main
      1 /*
      2  * Mesa 3-D graphics library
      3  * Version:  7.1
      4  *
      5  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the "Software"),
      9  * to deal in the Software without restriction, including without limitation
     10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     11  * and/or sell copies of the Software, and to permit persons to whom the
     12  * Software is furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included
     15  * in all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     21  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     23  */
     24 
     25 #include "glheader.h"
     26 #include "imports.h"
     27 #include "bufferobj.h"
     28 #include "context.h"
     29 #include "enums.h"
     30 #include "readpix.h"
     31 #include "framebuffer.h"
     32 #include "formats.h"
     33 #include "format_unpack.h"
     34 #include "image.h"
     35 #include "mtypes.h"
     36 #include "pack.h"
     37 #include "pbo.h"
     38 #include "state.h"
     39 #include "glformats.h"
     40 #include "fbobject.h"
     41 #include "teximage.h"
     42 
     43 /* Inexplicably, GL_HALF_FLOAT_OES has a different value than GL_HALF_FLOAT.
     44  */
     45 #ifndef GL_HALF_FLOAT_OES
     46 #define GL_HALF_FLOAT_OES 0x8D61
     47 #endif
     48 
     49 /**
     50  * Tries to implement glReadPixels() of GL_DEPTH_COMPONENT using memcpy of the
     51  * mapping.
     52  */
     53 static GLboolean
     54 fast_read_depth_pixels( struct gl_context *ctx,
     55 			GLint x, GLint y,
     56 			GLsizei width, GLsizei height,
     57 			GLenum type, GLvoid *pixels,
     58 			const struct gl_pixelstore_attrib *packing )
     59 {
     60    struct gl_framebuffer *fb = ctx->ReadBuffer;
     61    struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
     62    GLubyte *map, *dst;
     63    int stride, dstStride, j;
     64 
     65    if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0)
     66       return GL_FALSE;
     67 
     68    if (packing->SwapBytes)
     69       return GL_FALSE;
     70 
     71    if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_NORMALIZED)
     72       return GL_FALSE;
     73 
     74    if (!((type == GL_UNSIGNED_SHORT && rb->Format == MESA_FORMAT_Z16) ||
     75 	 type == GL_UNSIGNED_INT))
     76       return GL_FALSE;
     77 
     78    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
     79 			       &map, &stride);
     80 
     81    if (!map) {
     82       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
     83       return GL_TRUE;  /* don't bother trying the slow path */
     84    }
     85 
     86    dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type);
     87    dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
     88 					   GL_DEPTH_COMPONENT, type, 0, 0);
     89 
     90    for (j = 0; j < height; j++) {
     91       if (type == GL_UNSIGNED_INT) {
     92 	 _mesa_unpack_uint_z_row(rb->Format, width, map, (GLuint *)dst);
     93       } else {
     94 	 ASSERT(type == GL_UNSIGNED_SHORT && rb->Format == MESA_FORMAT_Z16);
     95 	 memcpy(dst, map, width * 2);
     96       }
     97 
     98       map += stride;
     99       dst += dstStride;
    100    }
    101    ctx->Driver.UnmapRenderbuffer(ctx, rb);
    102 
    103    return GL_TRUE;
    104 }
    105 
    106 /**
    107  * Read pixels for format=GL_DEPTH_COMPONENT.
    108  */
    109 static void
    110 read_depth_pixels( struct gl_context *ctx,
    111                    GLint x, GLint y,
    112                    GLsizei width, GLsizei height,
    113                    GLenum type, GLvoid *pixels,
    114                    const struct gl_pixelstore_attrib *packing )
    115 {
    116    struct gl_framebuffer *fb = ctx->ReadBuffer;
    117    struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
    118    GLint j;
    119    GLubyte *dst, *map;
    120    int dstStride, stride;
    121    GLfloat *depthValues;
    122 
    123    if (!rb)
    124       return;
    125 
    126    /* clipping should have been done already */
    127    ASSERT(x >= 0);
    128    ASSERT(y >= 0);
    129    ASSERT(x + width <= (GLint) rb->Width);
    130    ASSERT(y + height <= (GLint) rb->Height);
    131 
    132    if (fast_read_depth_pixels(ctx, x, y, width, height, type, pixels, packing))
    133       return;
    134 
    135    dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type);
    136    dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
    137 					   GL_DEPTH_COMPONENT, type, 0, 0);
    138 
    139    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
    140 			       &map, &stride);
    141    if (!map) {
    142       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
    143       return;
    144    }
    145 
    146    depthValues = (GLfloat *) malloc(width * sizeof(GLfloat));
    147 
    148    if (depthValues) {
    149       /* General case (slower) */
    150       for (j = 0; j < height; j++, y++) {
    151          _mesa_unpack_float_z_row(rb->Format, width, map, depthValues);
    152          _mesa_pack_depth_span(ctx, width, dst, type, depthValues, packing);
    153 
    154          dst += dstStride;
    155          map += stride;
    156       }
    157    }
    158    else {
    159       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
    160    }
    161 
    162    free(depthValues);
    163 
    164    ctx->Driver.UnmapRenderbuffer(ctx, rb);
    165 }
    166 
    167 
    168 /**
    169  * Read pixels for format=GL_STENCIL_INDEX.
    170  */
    171 static void
    172 read_stencil_pixels( struct gl_context *ctx,
    173                      GLint x, GLint y,
    174                      GLsizei width, GLsizei height,
    175                      GLenum type, GLvoid *pixels,
    176                      const struct gl_pixelstore_attrib *packing )
    177 {
    178    struct gl_framebuffer *fb = ctx->ReadBuffer;
    179    struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
    180    GLint j;
    181    GLubyte *map, *stencil;
    182    GLint stride;
    183 
    184    if (!rb)
    185       return;
    186 
    187    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
    188 			       &map, &stride);
    189    if (!map) {
    190       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
    191       return;
    192    }
    193 
    194    stencil = (GLubyte *) malloc(width * sizeof(GLubyte));
    195 
    196    if (stencil) {
    197       /* process image row by row */
    198       for (j = 0; j < height; j++) {
    199          GLvoid *dest;
    200 
    201          _mesa_unpack_ubyte_stencil_row(rb->Format, width, map, stencil);
    202          dest = _mesa_image_address2d(packing, pixels, width, height,
    203                                       GL_STENCIL_INDEX, type, j, 0);
    204 
    205          _mesa_pack_stencil_span(ctx, width, type, dest, stencil, packing);
    206 
    207          map += stride;
    208       }
    209    }
    210    else {
    211       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
    212    }
    213 
    214    free(stencil);
    215 
    216    ctx->Driver.UnmapRenderbuffer(ctx, rb);
    217 }
    218 
    219 
    220 /**
    221  * Try to do glReadPixels of RGBA data using a simple memcpy or swizzle.
    222  * \return GL_TRUE if successful, GL_FALSE otherwise (use the slow path)
    223  */
    224 static GLboolean
    225 fast_read_rgba_pixels_memcpy( struct gl_context *ctx,
    226 			      GLint x, GLint y,
    227 			      GLsizei width, GLsizei height,
    228 			      GLenum format, GLenum type,
    229 			      GLvoid *pixels,
    230 			      const struct gl_pixelstore_attrib *packing,
    231 			      GLbitfield transferOps )
    232 {
    233    struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
    234    GLubyte *dst, *map;
    235    int dstStride, stride, j, texelBytes;
    236    GLboolean swizzle_rb = GL_FALSE, copy_xrgb = GL_FALSE;
    237 
    238    /* XXX we could check for other swizzle/special cases here as needed */
    239    if (rb->Format == MESA_FORMAT_RGBA8888_REV &&
    240        format == GL_BGRA &&
    241        type == GL_UNSIGNED_INT_8_8_8_8_REV &&
    242        !ctx->Pack.SwapBytes) {
    243       swizzle_rb = GL_TRUE;
    244    }
    245    else if (rb->Format == MESA_FORMAT_XRGB8888 &&
    246        format == GL_BGRA &&
    247        type == GL_UNSIGNED_INT_8_8_8_8_REV &&
    248        !ctx->Pack.SwapBytes) {
    249       copy_xrgb = GL_TRUE;
    250    }
    251    else if (!_mesa_format_matches_format_and_type(rb->Format, format, type,
    252                                                   ctx->Pack.SwapBytes))
    253       return GL_FALSE;
    254 
    255    /* If the format is unsigned normalized then we can ignore clamping
    256     * because the values are already in the range [0,1] so it won't
    257     * have any effect anyway.
    258     */
    259    if (_mesa_get_format_datatype(rb->Format) == GL_UNSIGNED_NORMALIZED)
    260       transferOps &= ~IMAGE_CLAMP_BIT;
    261 
    262    if (transferOps)
    263       return GL_FALSE;
    264 
    265    dstStride = _mesa_image_row_stride(packing, width, format, type);
    266    dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
    267 					   format, type, 0, 0);
    268 
    269    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
    270 			       &map, &stride);
    271    if (!map) {
    272       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
    273       return GL_TRUE;  /* don't bother trying the slow path */
    274    }
    275 
    276    texelBytes = _mesa_get_format_bytes(rb->Format);
    277 
    278    if (swizzle_rb) {
    279       /* swap R/B */
    280       for (j = 0; j < height; j++) {
    281          int i;
    282          for (i = 0; i < width; i++) {
    283             GLuint *dst4 = (GLuint *) dst, *map4 = (GLuint *) map;
    284             GLuint pixel = map4[i];
    285             dst4[i] = (pixel & 0xff00ff00)
    286                    | ((pixel & 0x00ff0000) >> 16)
    287                    | ((pixel & 0x000000ff) << 16);
    288          }
    289          dst += dstStride;
    290          map += stride;
    291       }
    292    } else if (copy_xrgb) {
    293       /* convert xrgb -> argb */
    294       for (j = 0; j < height; j++) {
    295          GLuint *dst4 = (GLuint *) dst, *map4 = (GLuint *) map;
    296          int i;
    297          for (i = 0; i < width; i++) {
    298             dst4[i] = map4[i] | 0xff000000;  /* set A=0xff */
    299          }
    300          dst += dstStride;
    301          map += stride;
    302       }
    303    } else {
    304       /* just memcpy */
    305       for (j = 0; j < height; j++) {
    306          memcpy(dst, map, width * texelBytes);
    307          dst += dstStride;
    308          map += stride;
    309       }
    310    }
    311 
    312    ctx->Driver.UnmapRenderbuffer(ctx, rb);
    313 
    314    return GL_TRUE;
    315 }
    316 
    317 static void
    318 slow_read_rgba_pixels( struct gl_context *ctx,
    319 		       GLint x, GLint y,
    320 		       GLsizei width, GLsizei height,
    321 		       GLenum format, GLenum type,
    322 		       GLvoid *pixels,
    323 		       const struct gl_pixelstore_attrib *packing,
    324 		       GLbitfield transferOps )
    325 {
    326    struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
    327    const gl_format rbFormat = _mesa_get_srgb_format_linear(rb->Format);
    328    void *rgba;
    329    GLubyte *dst, *map;
    330    int dstStride, stride, j;
    331    GLboolean dst_is_integer = _mesa_is_enum_format_integer(format);
    332    GLboolean dst_is_uint = _mesa_is_format_unsigned(rbFormat);
    333 
    334    dstStride = _mesa_image_row_stride(packing, width, format, type);
    335    dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
    336 					   format, type, 0, 0);
    337 
    338    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
    339 			       &map, &stride);
    340    if (!map) {
    341       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
    342       return;
    343    }
    344 
    345    rgba = malloc(width * MAX_PIXEL_BYTES);
    346    if (!rgba)
    347       goto done;
    348 
    349    for (j = 0; j < height; j++) {
    350       if (dst_is_integer) {
    351 	 _mesa_unpack_uint_rgba_row(rbFormat, width, map, (GLuint (*)[4]) rgba);
    352          _mesa_rebase_rgba_uint(width, (GLuint (*)[4]) rgba,
    353                                 rb->_BaseFormat);
    354          if (dst_is_uint) {
    355             _mesa_pack_rgba_span_from_uints(ctx, width, (GLuint (*)[4]) rgba, format,
    356                                             type, dst);
    357          } else {
    358             _mesa_pack_rgba_span_from_ints(ctx, width, (GLint (*)[4]) rgba, format,
    359                                            type, dst);
    360          }
    361       } else {
    362 	 _mesa_unpack_rgba_row(rbFormat, width, map, (GLfloat (*)[4]) rgba);
    363          _mesa_rebase_rgba_float(width, (GLfloat (*)[4]) rgba,
    364                                  rb->_BaseFormat);
    365 	 _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format,
    366                                     type, dst, packing, transferOps);
    367       }
    368       dst += dstStride;
    369       map += stride;
    370    }
    371 
    372    free(rgba);
    373 
    374 done:
    375    ctx->Driver.UnmapRenderbuffer(ctx, rb);
    376 }
    377 
    378 /*
    379  * Read R, G, B, A, RGB, L, or LA pixels.
    380  */
    381 static void
    382 read_rgba_pixels( struct gl_context *ctx,
    383                   GLint x, GLint y,
    384                   GLsizei width, GLsizei height,
    385                   GLenum format, GLenum type, GLvoid *pixels,
    386                   const struct gl_pixelstore_attrib *packing )
    387 {
    388    GLbitfield transferOps = ctx->_ImageTransferState;
    389    struct gl_framebuffer *fb = ctx->ReadBuffer;
    390    struct gl_renderbuffer *rb = fb->_ColorReadBuffer;
    391 
    392    if (!rb)
    393       return;
    394 
    395    if ((ctx->Color._ClampReadColor == GL_TRUE || type != GL_FLOAT) &&
    396        !_mesa_is_enum_format_integer(format)) {
    397       transferOps |= IMAGE_CLAMP_BIT;
    398    }
    399 
    400    /* Try the optimized paths first. */
    401    if (fast_read_rgba_pixels_memcpy(ctx, x, y, width, height,
    402                                     format, type, pixels, packing,
    403                                     transferOps)) {
    404       return;
    405    }
    406 
    407    slow_read_rgba_pixels(ctx, x, y, width, height,
    408 			 format, type, pixels, packing, transferOps);
    409 }
    410 
    411 /**
    412  * For a packed depth/stencil buffer being read as depth/stencil, just memcpy the
    413  * data (possibly swapping 8/24 vs 24/8 as we go).
    414  */
    415 static GLboolean
    416 fast_read_depth_stencil_pixels(struct gl_context *ctx,
    417 			       GLint x, GLint y,
    418 			       GLsizei width, GLsizei height,
    419 			       GLubyte *dst, int dstStride)
    420 {
    421    struct gl_framebuffer *fb = ctx->ReadBuffer;
    422    struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
    423    struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
    424    GLubyte *map;
    425    int stride, i;
    426 
    427    if (rb != stencilRb)
    428       return GL_FALSE;
    429 
    430    if (rb->Format != MESA_FORMAT_Z24_S8 &&
    431        rb->Format != MESA_FORMAT_S8_Z24)
    432       return GL_FALSE;
    433 
    434    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
    435 			       &map, &stride);
    436    if (!map) {
    437       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
    438       return GL_TRUE;  /* don't bother trying the slow path */
    439    }
    440 
    441    for (i = 0; i < height; i++) {
    442       _mesa_unpack_uint_24_8_depth_stencil_row(rb->Format, width,
    443 					       map, (GLuint *)dst);
    444       map += stride;
    445       dst += dstStride;
    446    }
    447 
    448    ctx->Driver.UnmapRenderbuffer(ctx, rb);
    449 
    450    return GL_TRUE;
    451 }
    452 
    453 
    454 /**
    455  * For non-float-depth and stencil buffers being read as 24/8 depth/stencil,
    456  * copy the integer data directly instead of converting depth to float and
    457  * re-packing.
    458  */
    459 static GLboolean
    460 fast_read_depth_stencil_pixels_separate(struct gl_context *ctx,
    461 					GLint x, GLint y,
    462 					GLsizei width, GLsizei height,
    463 					uint32_t *dst, int dstStride)
    464 {
    465    struct gl_framebuffer *fb = ctx->ReadBuffer;
    466    struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
    467    struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
    468    GLubyte *depthMap, *stencilMap, *stencilVals;
    469    int depthStride, stencilStride, i, j;
    470 
    471    if (_mesa_get_format_datatype(depthRb->Format) != GL_UNSIGNED_NORMALIZED)
    472       return GL_FALSE;
    473 
    474    ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
    475 			       GL_MAP_READ_BIT, &depthMap, &depthStride);
    476    if (!depthMap) {
    477       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
    478       return GL_TRUE;  /* don't bother trying the slow path */
    479    }
    480 
    481    ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
    482 			       GL_MAP_READ_BIT, &stencilMap, &stencilStride);
    483    if (!stencilMap) {
    484       ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
    485       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
    486       return GL_TRUE;  /* don't bother trying the slow path */
    487    }
    488 
    489    stencilVals = (GLubyte *) malloc(width * sizeof(GLubyte));
    490 
    491    if (stencilVals) {
    492       for (j = 0; j < height; j++) {
    493          _mesa_unpack_uint_z_row(depthRb->Format, width, depthMap, dst);
    494          _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width,
    495                                         stencilMap, stencilVals);
    496 
    497          for (i = 0; i < width; i++) {
    498             dst[i] = (dst[i] & 0xffffff00) | stencilVals[i];
    499          }
    500 
    501          depthMap += depthStride;
    502          stencilMap += stencilStride;
    503          dst += dstStride / 4;
    504       }
    505    }
    506    else {
    507       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
    508    }
    509 
    510    free(stencilVals);
    511 
    512    ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
    513    ctx->Driver.UnmapRenderbuffer(ctx, stencilRb);
    514 
    515    return GL_TRUE;
    516 }
    517 
    518 static void
    519 slow_read_depth_stencil_pixels_separate(struct gl_context *ctx,
    520 					GLint x, GLint y,
    521 					GLsizei width, GLsizei height,
    522 					GLenum type,
    523 					const struct gl_pixelstore_attrib *packing,
    524 					GLubyte *dst, int dstStride)
    525 {
    526    struct gl_framebuffer *fb = ctx->ReadBuffer;
    527    struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
    528    struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
    529    GLubyte *depthMap, *stencilMap;
    530    int depthStride, stencilStride, j;
    531    GLubyte *stencilVals;
    532    GLfloat *depthVals;
    533 
    534 
    535    /* The depth and stencil buffers might be separate, or a single buffer.
    536     * If one buffer, only map it once.
    537     */
    538    ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
    539 			       GL_MAP_READ_BIT, &depthMap, &depthStride);
    540    if (!depthMap) {
    541       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
    542       return;
    543    }
    544 
    545    if (stencilRb != depthRb) {
    546       ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
    547                                   GL_MAP_READ_BIT, &stencilMap,
    548                                   &stencilStride);
    549       if (!stencilMap) {
    550          ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
    551          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
    552          return;
    553       }
    554    }
    555    else {
    556       stencilMap = depthMap;
    557       stencilStride = depthStride;
    558    }
    559 
    560    stencilVals = (GLubyte *) malloc(width * sizeof(GLubyte));
    561    depthVals = (GLfloat *) malloc(width * sizeof(GLfloat));
    562 
    563    if (stencilVals && depthVals) {
    564       for (j = 0; j < height; j++) {
    565          _mesa_unpack_float_z_row(depthRb->Format, width, depthMap, depthVals);
    566          _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width,
    567                                         stencilMap, stencilVals);
    568 
    569          _mesa_pack_depth_stencil_span(ctx, width, type, (GLuint *)dst,
    570                                        depthVals, stencilVals, packing);
    571 
    572          depthMap += depthStride;
    573          stencilMap += stencilStride;
    574          dst += dstStride;
    575       }
    576    }
    577    else {
    578       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
    579    }
    580 
    581    free(stencilVals);
    582    free(depthVals);
    583 
    584    ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
    585    if (stencilRb != depthRb) {
    586       ctx->Driver.UnmapRenderbuffer(ctx, stencilRb);
    587    }
    588 }
    589 
    590 
    591 /**
    592  * Read combined depth/stencil values.
    593  * We'll have already done error checking to be sure the expected
    594  * depth and stencil buffers really exist.
    595  */
    596 static void
    597 read_depth_stencil_pixels(struct gl_context *ctx,
    598                           GLint x, GLint y,
    599                           GLsizei width, GLsizei height,
    600                           GLenum type, GLvoid *pixels,
    601                           const struct gl_pixelstore_attrib *packing )
    602 {
    603    const GLboolean scaleOrBias
    604       = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
    605    const GLboolean stencilTransfer = ctx->Pixel.IndexShift
    606       || ctx->Pixel.IndexOffset || ctx->Pixel.MapStencilFlag;
    607    GLubyte *dst;
    608    int dstStride;
    609 
    610    dst = (GLubyte *) _mesa_image_address2d(packing, pixels,
    611 					   width, height,
    612 					   GL_DEPTH_STENCIL_EXT,
    613 					   type, 0, 0);
    614    dstStride = _mesa_image_row_stride(packing, width,
    615 				      GL_DEPTH_STENCIL_EXT, type);
    616 
    617    /* Fast 24/8 reads. */
    618    if (type == GL_UNSIGNED_INT_24_8 &&
    619        !scaleOrBias && !stencilTransfer && !packing->SwapBytes) {
    620       if (fast_read_depth_stencil_pixels(ctx, x, y, width, height,
    621 					 dst, dstStride))
    622 	 return;
    623 
    624       if (fast_read_depth_stencil_pixels_separate(ctx, x, y, width, height,
    625 						  (uint32_t *)dst, dstStride))
    626 	 return;
    627    }
    628 
    629    slow_read_depth_stencil_pixels_separate(ctx, x, y, width, height,
    630 					   type, packing,
    631 					   dst, dstStride);
    632 }
    633 
    634 
    635 
    636 /**
    637  * Software fallback routine for ctx->Driver.ReadPixels().
    638  * By time we get here, all error checking will have been done.
    639  */
    640 void
    641 _mesa_readpixels(struct gl_context *ctx,
    642                  GLint x, GLint y, GLsizei width, GLsizei height,
    643                  GLenum format, GLenum type,
    644                  const struct gl_pixelstore_attrib *packing,
    645                  GLvoid *pixels)
    646 {
    647    struct gl_pixelstore_attrib clippedPacking = *packing;
    648 
    649    if (ctx->NewState)
    650       _mesa_update_state(ctx);
    651 
    652    /* Do all needed clipping here, so that we can forget about it later */
    653    if (_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking)) {
    654 
    655       pixels = _mesa_map_pbo_dest(ctx, &clippedPacking, pixels);
    656 
    657       if (pixels) {
    658          switch (format) {
    659          case GL_STENCIL_INDEX:
    660             read_stencil_pixels(ctx, x, y, width, height, type, pixels,
    661                                 &clippedPacking);
    662             break;
    663          case GL_DEPTH_COMPONENT:
    664             read_depth_pixels(ctx, x, y, width, height, type, pixels,
    665                               &clippedPacking);
    666             break;
    667          case GL_DEPTH_STENCIL_EXT:
    668             read_depth_stencil_pixels(ctx, x, y, width, height, type, pixels,
    669                                       &clippedPacking);
    670             break;
    671          default:
    672             /* all other formats should be color formats */
    673             read_rgba_pixels(ctx, x, y, width, height, format, type, pixels,
    674                              &clippedPacking);
    675          }
    676 
    677          _mesa_unmap_pbo_dest(ctx, &clippedPacking);
    678       }
    679    }
    680 }
    681 
    682 
    683 void GLAPIENTRY
    684 _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
    685 		      GLenum format, GLenum type, GLsizei bufSize,
    686                       GLvoid *pixels )
    687 {
    688    GLenum err;
    689 
    690    GET_CURRENT_CONTEXT(ctx);
    691    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
    692 
    693    FLUSH_CURRENT(ctx, 0);
    694 
    695    if (MESA_VERBOSE & VERBOSE_API)
    696       _mesa_debug(ctx, "glReadPixels(%d, %d, %s, %s, %p)\n",
    697                   width, height,
    698                   _mesa_lookup_enum_by_nr(format),
    699                   _mesa_lookup_enum_by_nr(type),
    700                   pixels);
    701 
    702    if (width < 0 || height < 0) {
    703       _mesa_error( ctx, GL_INVALID_VALUE,
    704                    "glReadPixels(width=%d height=%d)", width, height );
    705       return;
    706    }
    707 
    708    /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
    709     * combinations of format and type that can be used.
    710     *
    711     * Technically, only two combinations are actually allowed:
    712     * GL_RGBA/GL_UNSIGNED_BYTE, and some implementation-specific internal
    713     * preferred combination.  This code doesn't know what that preferred
    714     * combination is, and Mesa can handle anything valid.  Just work instead.
    715     */
    716    if (_mesa_is_gles(ctx) && ctx->Version < 30) {
    717       err = _mesa_es_error_check_format_and_type(format, type, 2);
    718       if (err == GL_NO_ERROR) {
    719          if (type == GL_FLOAT || type == GL_HALF_FLOAT_OES) {
    720             err = GL_INVALID_OPERATION;
    721          } else if (format == GL_DEPTH_COMPONENT
    722                     || format == GL_DEPTH_STENCIL) {
    723             err = GL_INVALID_ENUM;
    724          }
    725       }
    726 
    727       if (err != GL_NO_ERROR) {
    728          _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
    729                      _mesa_lookup_enum_by_nr(format),
    730                      _mesa_lookup_enum_by_nr(type));
    731          return;
    732       }
    733    }
    734 
    735    if (ctx->NewState)
    736       _mesa_update_state(ctx);
    737 
    738    err = _mesa_error_check_format_and_type(ctx, format, type);
    739    if (err != GL_NO_ERROR) {
    740       _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
    741                   _mesa_lookup_enum_by_nr(format),
    742                   _mesa_lookup_enum_by_nr(type));
    743       return;
    744    }
    745 
    746    if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
    747       _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
    748                   "glReadPixels(incomplete framebuffer)" );
    749       return;
    750    }
    751 
    752    if (_mesa_is_user_fbo(ctx->ReadBuffer) &&
    753        ctx->ReadBuffer->Visual.samples > 0) {
    754       _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)");
    755       return;
    756    }
    757 
    758    if (!_mesa_source_buffer_exists(ctx, format)) {
    759       _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(no readbuffer)");
    760       return;
    761    }
    762 
    763    /* Check that the destination format and source buffer are both
    764     * integer-valued or both non-integer-valued.
    765     */
    766    if (ctx->Extensions.EXT_texture_integer && _mesa_is_color_format(format)) {
    767       const struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
    768       const GLboolean srcInteger = _mesa_is_format_integer_color(rb->Format);
    769       const GLboolean dstInteger = _mesa_is_enum_format_integer(format);
    770       if (dstInteger != srcInteger) {
    771          _mesa_error(ctx, GL_INVALID_OPERATION,
    772                      "glReadPixels(integer / non-integer format mismatch");
    773          return;
    774       }
    775    }
    776 
    777    if (width == 0 || height == 0)
    778       return; /* nothing to do */
    779 
    780    if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1,
    781                                   format, type, bufSize, pixels)) {
    782       if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
    783          _mesa_error(ctx, GL_INVALID_OPERATION,
    784                      "glReadPixels(out of bounds PBO access)");
    785       } else {
    786          _mesa_error(ctx, GL_INVALID_OPERATION,
    787                      "glReadnPixelsARB(out of bounds access:"
    788                      " bufSize (%d) is too small)", bufSize);
    789       }
    790       return;
    791    }
    792 
    793    if (_mesa_is_bufferobj(ctx->Pack.BufferObj) &&
    794        _mesa_bufferobj_mapped(ctx->Pack.BufferObj)) {
    795       /* buffer is mapped - that's an error */
    796       _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
    797       return;
    798    }
    799 
    800    ctx->Driver.ReadPixels(ctx, x, y, width, height,
    801 			  format, type, &ctx->Pack, pixels);
    802 }
    803 
    804 void GLAPIENTRY
    805 _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
    806 		  GLenum format, GLenum type, GLvoid *pixels )
    807 {
    808    _mesa_ReadnPixelsARB(x, y, width, height, format, type, INT_MAX, pixels);
    809 }
    810