Home | History | Annotate | Download | only in swrast
      1 /*
      2  * Mesa 3-D graphics library
      3  * Version:  7.1
      4  *
      5  * Copyright (C) 1999-2007  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 
     26 #include "main/glheader.h"
     27 #include "main/bufferobj.h"
     28 #include "main/colormac.h"
     29 #include "main/condrender.h"
     30 #include "main/context.h"
     31 #include "main/format_pack.h"
     32 #include "main/image.h"
     33 #include "main/imports.h"
     34 #include "main/macros.h"
     35 #include "main/pack.h"
     36 #include "main/pbo.h"
     37 #include "main/pixeltransfer.h"
     38 #include "main/state.h"
     39 
     40 #include "s_context.h"
     41 #include "s_span.h"
     42 #include "s_stencil.h"
     43 #include "s_zoom.h"
     44 
     45 
     46 /**
     47  * Handle a common case of drawing GL_RGB/GL_UNSIGNED_BYTE into a
     48  * MESA_FORMAT_XRGB888 or MESA_FORMAT_ARGB888 renderbuffer.
     49  */
     50 static void
     51 fast_draw_rgb_ubyte_pixels(struct gl_context *ctx,
     52                            struct gl_renderbuffer *rb,
     53                            GLint x, GLint y,
     54                            GLsizei width, GLsizei height,
     55                            const struct gl_pixelstore_attrib *unpack,
     56                            const GLvoid *pixels)
     57 {
     58    const GLubyte *src = (const GLubyte *)
     59       _mesa_image_address2d(unpack, pixels, width,
     60                             height, GL_RGB, GL_UNSIGNED_BYTE, 0, 0);
     61    const GLint srcRowStride = _mesa_image_row_stride(unpack, width,
     62                                                      GL_RGB, GL_UNSIGNED_BYTE);
     63    GLint i, j;
     64    GLubyte *dst;
     65    GLint dstRowStride;
     66 
     67    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
     68                                GL_MAP_WRITE_BIT, &dst, &dstRowStride);
     69 
     70    if (!dst) {
     71       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
     72       return;
     73    }
     74 
     75    if (ctx->Pixel.ZoomY == -1.0f) {
     76       dst = dst + (height - 1) * dstRowStride;
     77       dstRowStride = -dstRowStride;
     78    }
     79 
     80    for (i = 0; i < height; i++) {
     81       GLuint *dst4 = (GLuint *) dst;
     82       for (j = 0; j < width; j++) {
     83          dst4[j] = PACK_COLOR_8888(0xff, src[j*3+0], src[j*3+1], src[j*3+2]);
     84       }
     85       dst += dstRowStride;
     86       src += srcRowStride;
     87    }
     88 
     89    ctx->Driver.UnmapRenderbuffer(ctx, rb);
     90 }
     91 
     92 
     93 /**
     94  * Handle a common case of drawing GL_RGBA/GL_UNSIGNED_BYTE into a
     95  * MESA_FORMAT_ARGB888 or MESA_FORMAT_xRGB888 renderbuffer.
     96  */
     97 static void
     98 fast_draw_rgba_ubyte_pixels(struct gl_context *ctx,
     99                            struct gl_renderbuffer *rb,
    100                            GLint x, GLint y,
    101                            GLsizei width, GLsizei height,
    102                            const struct gl_pixelstore_attrib *unpack,
    103                            const GLvoid *pixels)
    104 {
    105    const GLubyte *src = (const GLubyte *)
    106       _mesa_image_address2d(unpack, pixels, width,
    107                             height, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
    108    const GLint srcRowStride =
    109       _mesa_image_row_stride(unpack, width, GL_RGBA, GL_UNSIGNED_BYTE);
    110    GLint i, j;
    111    GLubyte *dst;
    112    GLint dstRowStride;
    113 
    114    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
    115                                GL_MAP_WRITE_BIT, &dst, &dstRowStride);
    116 
    117    if (!dst) {
    118       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
    119       return;
    120    }
    121 
    122    if (ctx->Pixel.ZoomY == -1.0f) {
    123       dst = dst + (height - 1) * dstRowStride;
    124       dstRowStride = -dstRowStride;
    125    }
    126 
    127    for (i = 0; i < height; i++) {
    128       GLuint *dst4 = (GLuint *) dst;
    129       for (j = 0; j < width; j++) {
    130          dst4[j] = PACK_COLOR_8888(src[j*4+3], src[j*4+0],
    131                                    src[j*4+1], src[j*4+2]);
    132       }
    133       dst += dstRowStride;
    134       src += srcRowStride;
    135    }
    136 
    137    ctx->Driver.UnmapRenderbuffer(ctx, rb);
    138 }
    139 
    140 
    141 /**
    142  * Handle a common case of drawing a format/type combination that
    143  * exactly matches the renderbuffer format.
    144  */
    145 static void
    146 fast_draw_generic_pixels(struct gl_context *ctx,
    147                          struct gl_renderbuffer *rb,
    148                          GLint x, GLint y,
    149                          GLsizei width, GLsizei height,
    150                          GLenum format, GLenum type,
    151                          const struct gl_pixelstore_attrib *unpack,
    152                          const GLvoid *pixels)
    153 {
    154    const GLubyte *src = (const GLubyte *)
    155       _mesa_image_address2d(unpack, pixels, width,
    156                             height, format, type, 0, 0);
    157    const GLint srcRowStride =
    158       _mesa_image_row_stride(unpack, width, format, type);
    159    const GLint rowLength = width * _mesa_get_format_bytes(rb->Format);
    160    GLint i;
    161    GLubyte *dst;
    162    GLint dstRowStride;
    163 
    164    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
    165                                GL_MAP_WRITE_BIT, &dst, &dstRowStride);
    166 
    167    if (!dst) {
    168       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
    169       return;
    170    }
    171 
    172    if (ctx->Pixel.ZoomY == -1.0f) {
    173       dst = dst + (height - 1) * dstRowStride;
    174       dstRowStride = -dstRowStride;
    175    }
    176 
    177    for (i = 0; i < height; i++) {
    178       memcpy(dst, src, rowLength);
    179       dst += dstRowStride;
    180       src += srcRowStride;
    181    }
    182 
    183    ctx->Driver.UnmapRenderbuffer(ctx, rb);
    184 }
    185 
    186 
    187 /**
    188  * Try to do a fast and simple RGB(a) glDrawPixels.
    189  * Return:  GL_TRUE if success, GL_FALSE if slow path must be used instead
    190  */
    191 static GLboolean
    192 fast_draw_rgba_pixels(struct gl_context *ctx, GLint x, GLint y,
    193                       GLsizei width, GLsizei height,
    194                       GLenum format, GLenum type,
    195                       const struct gl_pixelstore_attrib *userUnpack,
    196                       const GLvoid *pixels)
    197 {
    198    struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
    199    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    200    struct gl_pixelstore_attrib unpack;
    201 
    202    if (!rb)
    203       return GL_TRUE; /* no-op */
    204 
    205    if (ctx->DrawBuffer->_NumColorDrawBuffers > 1 ||
    206        (swrast->_RasterMask & ~CLIP_BIT) ||
    207        ctx->Texture._EnabledCoordUnits ||
    208        userUnpack->SwapBytes ||
    209        ctx->Pixel.ZoomX != 1.0f ||
    210        fabsf(ctx->Pixel.ZoomY) != 1.0f ||
    211        ctx->_ImageTransferState) {
    212       /* can't handle any of those conditions */
    213       return GL_FALSE;
    214    }
    215 
    216    unpack = *userUnpack;
    217 
    218    /* clipping */
    219    if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height, &unpack)) {
    220       /* image was completely clipped: no-op, all done */
    221       return GL_TRUE;
    222    }
    223 
    224    if (format == GL_RGB &&
    225        type == GL_UNSIGNED_BYTE &&
    226        (rb->Format == MESA_FORMAT_XRGB8888 ||
    227         rb->Format == MESA_FORMAT_ARGB8888)) {
    228       fast_draw_rgb_ubyte_pixels(ctx, rb, x, y, width, height,
    229                                  &unpack, pixels);
    230       return GL_TRUE;
    231    }
    232 
    233    if (format == GL_RGBA &&
    234        type == GL_UNSIGNED_BYTE &&
    235        (rb->Format == MESA_FORMAT_XRGB8888 ||
    236         rb->Format == MESA_FORMAT_ARGB8888)) {
    237       fast_draw_rgba_ubyte_pixels(ctx, rb, x, y, width, height,
    238                                   &unpack, pixels);
    239       return GL_TRUE;
    240    }
    241 
    242    if (_mesa_format_matches_format_and_type(rb->Format, format, type,
    243                                             ctx->Unpack.SwapBytes)) {
    244       fast_draw_generic_pixels(ctx, rb, x, y, width, height,
    245                                format, type, &unpack, pixels);
    246       return GL_TRUE;
    247    }
    248 
    249    /* can't handle this pixel format and/or data type */
    250    return GL_FALSE;
    251 }
    252 
    253 
    254 
    255 /*
    256  * Draw stencil image.
    257  */
    258 static void
    259 draw_stencil_pixels( struct gl_context *ctx, GLint x, GLint y,
    260                      GLsizei width, GLsizei height,
    261                      GLenum type,
    262                      const struct gl_pixelstore_attrib *unpack,
    263                      const GLvoid *pixels )
    264 {
    265    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
    266    const GLenum destType = GL_UNSIGNED_BYTE;
    267    GLint row;
    268    GLubyte *values;
    269 
    270    values = (GLubyte *) malloc(width * sizeof(GLubyte));
    271    if (!values) {
    272       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
    273       return;
    274    }
    275 
    276    for (row = 0; row < height; row++) {
    277       const GLvoid *source = _mesa_image_address2d(unpack, pixels,
    278                                                    width, height,
    279                                                    GL_STENCIL_INDEX, type,
    280                                                    row, 0);
    281       _mesa_unpack_stencil_span(ctx, width, destType, values,
    282                                 type, source, unpack,
    283                                 ctx->_ImageTransferState);
    284       if (zoom) {
    285          _swrast_write_zoomed_stencil_span(ctx, x, y, width,
    286                                            x, y, values);
    287       }
    288       else {
    289          _swrast_write_stencil_span(ctx, width, x, y, values);
    290       }
    291 
    292       y++;
    293    }
    294 
    295    free(values);
    296 }
    297 
    298 
    299 /*
    300  * Draw depth image.
    301  */
    302 static void
    303 draw_depth_pixels( struct gl_context *ctx, GLint x, GLint y,
    304                    GLsizei width, GLsizei height,
    305                    GLenum type,
    306                    const struct gl_pixelstore_attrib *unpack,
    307                    const GLvoid *pixels )
    308 {
    309    const GLboolean scaleOrBias
    310       = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
    311    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
    312    SWspan span;
    313 
    314    INIT_SPAN(span, GL_BITMAP);
    315    span.arrayMask = SPAN_Z;
    316    _swrast_span_default_attribs(ctx, &span);
    317 
    318    if (type == GL_UNSIGNED_SHORT
    319        && ctx->DrawBuffer->Visual.depthBits == 16
    320        && !scaleOrBias
    321        && !zoom
    322        && width <= SWRAST_MAX_WIDTH
    323        && !unpack->SwapBytes) {
    324       /* Special case: directly write 16-bit depth values */
    325       GLint row;
    326       for (row = 0; row < height; row++) {
    327          const GLushort *zSrc = (const GLushort *)
    328             _mesa_image_address2d(unpack, pixels, width, height,
    329                                   GL_DEPTH_COMPONENT, type, row, 0);
    330          GLint i;
    331          for (i = 0; i < width; i++)
    332             span.array->z[i] = zSrc[i];
    333          span.x = x;
    334          span.y = y + row;
    335          span.end = width;
    336          _swrast_write_rgba_span(ctx, &span);
    337       }
    338    }
    339    else if (type == GL_UNSIGNED_INT
    340             && !scaleOrBias
    341             && !zoom
    342             && width <= SWRAST_MAX_WIDTH
    343             && !unpack->SwapBytes) {
    344       /* Special case: shift 32-bit values down to Visual.depthBits */
    345       const GLint shift = 32 - ctx->DrawBuffer->Visual.depthBits;
    346       GLint row;
    347       for (row = 0; row < height; row++) {
    348          const GLuint *zSrc = (const GLuint *)
    349             _mesa_image_address2d(unpack, pixels, width, height,
    350                                   GL_DEPTH_COMPONENT, type, row, 0);
    351          if (shift == 0) {
    352             memcpy(span.array->z, zSrc, width * sizeof(GLuint));
    353          }
    354          else {
    355             GLint col;
    356             for (col = 0; col < width; col++)
    357                span.array->z[col] = zSrc[col] >> shift;
    358          }
    359          span.x = x;
    360          span.y = y + row;
    361          span.end = width;
    362          _swrast_write_rgba_span(ctx, &span);
    363       }
    364    }
    365    else {
    366       /* General case */
    367       const GLuint depthMax = ctx->DrawBuffer->_DepthMax;
    368       GLint skipPixels = 0;
    369 
    370       /* in case width > SWRAST_MAX_WIDTH do the copy in chunks */
    371       while (skipPixels < width) {
    372          const GLint spanWidth = MIN2(width - skipPixels, SWRAST_MAX_WIDTH);
    373          GLint row;
    374          ASSERT(span.end <= SWRAST_MAX_WIDTH);
    375          for (row = 0; row < height; row++) {
    376             const GLvoid *zSrc = _mesa_image_address2d(unpack,
    377                                                       pixels, width, height,
    378                                                       GL_DEPTH_COMPONENT, type,
    379                                                       row, skipPixels);
    380 
    381             /* Set these for each row since the _swrast_write_* function may
    382              * change them while clipping.
    383              */
    384             span.x = x + skipPixels;
    385             span.y = y + row;
    386             span.end = spanWidth;
    387 
    388             _mesa_unpack_depth_span(ctx, spanWidth,
    389                                     GL_UNSIGNED_INT, span.array->z, depthMax,
    390                                     type, zSrc, unpack);
    391             if (zoom) {
    392                _swrast_write_zoomed_depth_span(ctx, x, y, &span);
    393             }
    394             else {
    395                _swrast_write_rgba_span(ctx, &span);
    396             }
    397          }
    398          skipPixels += spanWidth;
    399       }
    400    }
    401 }
    402 
    403 
    404 
    405 /**
    406  * Draw RGBA image.
    407  */
    408 static void
    409 draw_rgba_pixels( struct gl_context *ctx, GLint x, GLint y,
    410                   GLsizei width, GLsizei height,
    411                   GLenum format, GLenum type,
    412                   const struct gl_pixelstore_attrib *unpack,
    413                   const GLvoid *pixels )
    414 {
    415    const GLint imgX = x, imgY = y;
    416    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
    417    GLfloat *convImage = NULL;
    418    GLbitfield transferOps = ctx->_ImageTransferState;
    419    SWspan span;
    420 
    421    /* Try an optimized glDrawPixels first */
    422    if (fast_draw_rgba_pixels(ctx, x, y, width, height, format, type,
    423                              unpack, pixels)) {
    424       return;
    425    }
    426 
    427    swrast_render_start(ctx);
    428 
    429    INIT_SPAN(span, GL_BITMAP);
    430    _swrast_span_default_attribs(ctx, &span);
    431    span.arrayMask = SPAN_RGBA;
    432    span.arrayAttribs = FRAG_BIT_COL0; /* we're fill in COL0 attrib values */
    433 
    434    if (ctx->DrawBuffer->_NumColorDrawBuffers > 0) {
    435       GLenum datatype = _mesa_get_format_datatype(
    436                  ctx->DrawBuffer->_ColorDrawBuffers[0]->Format);
    437       if (datatype != GL_FLOAT &&
    438           ctx->Color.ClampFragmentColor != GL_FALSE) {
    439          /* need to clamp colors before applying fragment ops */
    440          transferOps |= IMAGE_CLAMP_BIT;
    441       }
    442    }
    443 
    444    /*
    445     * General solution
    446     */
    447    {
    448       const GLbitfield interpMask = span.interpMask;
    449       const GLbitfield arrayMask = span.arrayMask;
    450       const GLint srcStride
    451          = _mesa_image_row_stride(unpack, width, format, type);
    452       GLint skipPixels = 0;
    453       /* use span array for temp color storage */
    454       GLfloat *rgba = (GLfloat *) span.array->attribs[FRAG_ATTRIB_COL0];
    455 
    456       /* if the span is wider than SWRAST_MAX_WIDTH we have to do it in chunks */
    457       while (skipPixels < width) {
    458          const GLint spanWidth = MIN2(width - skipPixels, SWRAST_MAX_WIDTH);
    459          const GLubyte *source
    460             = (const GLubyte *) _mesa_image_address2d(unpack, pixels,
    461                                                       width, height, format,
    462                                                       type, 0, skipPixels);
    463          GLint row;
    464 
    465          for (row = 0; row < height; row++) {
    466             /* get image row as float/RGBA */
    467             _mesa_unpack_color_span_float(ctx, spanWidth, GL_RGBA, rgba,
    468                                      format, type, source, unpack,
    469                                      transferOps);
    470 	    /* Set these for each row since the _swrast_write_* functions
    471 	     * may change them while clipping/rendering.
    472 	     */
    473 	    span.array->ChanType = GL_FLOAT;
    474 	    span.x = x + skipPixels;
    475 	    span.y = y + row;
    476 	    span.end = spanWidth;
    477 	    span.arrayMask = arrayMask;
    478 	    span.interpMask = interpMask;
    479 	    if (zoom) {
    480 	       _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span, rgba);
    481 	    }
    482 	    else {
    483 	       _swrast_write_rgba_span(ctx, &span);
    484 	    }
    485 
    486             source += srcStride;
    487          } /* for row */
    488 
    489          skipPixels += spanWidth;
    490       } /* while skipPixels < width */
    491 
    492       /* XXX this is ugly/temporary, to undo above change */
    493       span.array->ChanType = CHAN_TYPE;
    494    }
    495 
    496    if (convImage) {
    497       free(convImage);
    498    }
    499 
    500    swrast_render_finish(ctx);
    501 }
    502 
    503 
    504 /**
    505  * Draw depth+stencil values into a MESA_FORAMT_Z24_S8 or MESA_FORMAT_S8_Z24
    506  * renderbuffer.  No masking, zooming, scaling, etc.
    507  */
    508 static void
    509 fast_draw_depth_stencil(struct gl_context *ctx, GLint x, GLint y,
    510                         GLsizei width, GLsizei height,
    511                         const struct gl_pixelstore_attrib *unpack,
    512                         const GLvoid *pixels)
    513 {
    514    const GLenum format = GL_DEPTH_STENCIL_EXT;
    515    const GLenum type = GL_UNSIGNED_INT_24_8;
    516    struct gl_renderbuffer *rb =
    517       ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
    518    struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
    519    GLubyte *src, *dst;
    520    GLint srcRowStride, dstRowStride;
    521    GLint i;
    522 
    523    src = _mesa_image_address2d(unpack, pixels, width, height,
    524                                format, type, 0, 0);
    525    srcRowStride = _mesa_image_row_stride(unpack, width, format, type);
    526 
    527    dst = _swrast_pixel_address(rb, x, y);
    528    dstRowStride = srb->RowStride;
    529 
    530    for (i = 0; i < height; i++) {
    531       _mesa_pack_uint_24_8_depth_stencil_row(rb->Format, width,
    532                                              (const GLuint *) src, dst);
    533       dst += dstRowStride;
    534       src += srcRowStride;
    535    }
    536 }
    537 
    538 
    539 
    540 /**
    541  * This is a bit different from drawing GL_DEPTH_COMPONENT pixels.
    542  * The only per-pixel operations that apply are depth scale/bias,
    543  * stencil offset/shift, GL_DEPTH_WRITEMASK and GL_STENCIL_WRITEMASK,
    544  * and pixel zoom.
    545  * Also, only the depth buffer and stencil buffers are touched, not the
    546  * color buffer(s).
    547  */
    548 static void
    549 draw_depth_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
    550                           GLsizei width, GLsizei height, GLenum type,
    551                           const struct gl_pixelstore_attrib *unpack,
    552                           const GLvoid *pixels)
    553 {
    554    const GLint imgX = x, imgY = y;
    555    const GLboolean scaleOrBias
    556       = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
    557    const GLuint stencilMask = ctx->Stencil.WriteMask[0];
    558    const GLenum stencilType = GL_UNSIGNED_BYTE;
    559    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
    560    struct gl_renderbuffer *depthRb, *stencilRb;
    561    struct gl_pixelstore_attrib clippedUnpack = *unpack;
    562 
    563    if (!zoom) {
    564       if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height,
    565                                  &clippedUnpack)) {
    566          /* totally clipped */
    567          return;
    568       }
    569    }
    570 
    571    depthRb = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
    572    stencilRb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
    573    ASSERT(depthRb);
    574    ASSERT(stencilRb);
    575 
    576    if (depthRb == stencilRb &&
    577        (depthRb->Format == MESA_FORMAT_Z24_S8 ||
    578         depthRb->Format == MESA_FORMAT_S8_Z24) &&
    579        type == GL_UNSIGNED_INT_24_8 &&
    580        !scaleOrBias &&
    581        !zoom &&
    582        ctx->Depth.Mask &&
    583        (stencilMask & 0xff) == 0xff) {
    584       fast_draw_depth_stencil(ctx, x, y, width, height,
    585                               &clippedUnpack, pixels);
    586    }
    587    else {
    588       /* sub-optimal cases:
    589        * Separate depth/stencil buffers, or pixel transfer ops required.
    590        */
    591       /* XXX need to handle very wide images (skippixels) */
    592       GLuint *zValues;  /* 32-bit Z values */
    593       GLint i;
    594 
    595       zValues = (GLuint *) malloc(width * sizeof(GLuint));
    596       if (!zValues) {
    597          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
    598          return;
    599       }
    600 
    601       for (i = 0; i < height; i++) {
    602          const GLuint *depthStencilSrc = (const GLuint *)
    603             _mesa_image_address2d(&clippedUnpack, pixels, width, height,
    604                                   GL_DEPTH_STENCIL_EXT, type, i, 0);
    605 
    606          if (ctx->Depth.Mask) {
    607             _mesa_unpack_depth_span(ctx, width,
    608                                     GL_UNSIGNED_INT, /* dest type */
    609                                     zValues,         /* dest addr */
    610                                     0xffffffff,      /* depth max */
    611                                     type,            /* src type */
    612                                     depthStencilSrc, /* src addr */
    613                                     &clippedUnpack);
    614             if (zoom) {
    615                _swrast_write_zoomed_z_span(ctx, imgX, imgY, width, x,
    616                                            y + i, zValues);
    617             }
    618             else {
    619                GLubyte *dst = _swrast_pixel_address(depthRb, x, y + i);
    620                _mesa_pack_uint_z_row(depthRb->Format, width, zValues, dst);
    621             }
    622          }
    623 
    624          if (stencilMask != 0x0) {
    625             GLubyte *stencilValues = (GLubyte *) zValues; /* re-use buffer */
    626             /* get stencil values, with shift/offset/mapping */
    627             _mesa_unpack_stencil_span(ctx, width, stencilType, stencilValues,
    628                                       type, depthStencilSrc, &clippedUnpack,
    629                                       ctx->_ImageTransferState);
    630             if (zoom)
    631                _swrast_write_zoomed_stencil_span(ctx, imgX, imgY, width,
    632                                                   x, y + i, stencilValues);
    633             else
    634                _swrast_write_stencil_span(ctx, width, x, y + i, stencilValues);
    635          }
    636       }
    637 
    638       free(zValues);
    639    }
    640 }
    641 
    642 
    643 /**
    644  * Execute software-based glDrawPixels.
    645  * By time we get here, all error checking will have been done.
    646  */
    647 void
    648 _swrast_DrawPixels( struct gl_context *ctx,
    649 		    GLint x, GLint y,
    650 		    GLsizei width, GLsizei height,
    651 		    GLenum format, GLenum type,
    652 		    const struct gl_pixelstore_attrib *unpack,
    653 		    const GLvoid *pixels )
    654 {
    655    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    656    GLboolean save_vp_override = ctx->VertexProgram._Overriden;
    657 
    658    if (!_mesa_check_conditional_render(ctx))
    659       return; /* don't draw */
    660 
    661    /* We are creating fragments directly, without going through vertex
    662     * programs.
    663     *
    664     * This override flag tells the fragment processing code that its input
    665     * comes from a non-standard source, and it may therefore not rely on
    666     * optimizations that assume e.g. constant color if there is no color
    667     * vertex array.
    668     */
    669    _mesa_set_vp_override(ctx, GL_TRUE);
    670 
    671    if (ctx->NewState)
    672       _mesa_update_state(ctx);
    673 
    674    if (swrast->NewState)
    675       _swrast_validate_derived( ctx );
    676 
    677    pixels = _mesa_map_pbo_source(ctx, unpack, pixels);
    678    if (!pixels) {
    679       _mesa_set_vp_override(ctx, save_vp_override);
    680       return;
    681    }
    682 
    683    /*
    684     * By time we get here, all error checking should have been done.
    685     */
    686    switch (format) {
    687    case GL_STENCIL_INDEX:
    688       swrast_render_start(ctx);
    689       draw_stencil_pixels( ctx, x, y, width, height, type, unpack, pixels );
    690       swrast_render_finish(ctx);
    691       break;
    692    case GL_DEPTH_COMPONENT:
    693       swrast_render_start(ctx);
    694       draw_depth_pixels( ctx, x, y, width, height, type, unpack, pixels );
    695       swrast_render_finish(ctx);
    696       break;
    697    case GL_DEPTH_STENCIL_EXT:
    698       swrast_render_start(ctx);
    699       draw_depth_stencil_pixels(ctx, x, y, width, height, type, unpack, pixels);
    700       swrast_render_finish(ctx);
    701       break;
    702    default:
    703       /* all other formats should be color formats */
    704       draw_rgba_pixels(ctx, x, y, width, height, format, type, unpack, pixels);
    705    }
    706 
    707    _mesa_set_vp_override(ctx, save_vp_override);
    708 
    709    _mesa_unmap_pbo_source(ctx, unpack);
    710 }
    711