Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  20.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  21.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22.  * 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 = 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 = VARYING_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[VARYING_SLOT_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.    free(convImage);
  497.  
  498.    swrast_render_finish(ctx);
  499. }
  500.  
  501.  
  502. /**
  503.  * Draw depth+stencil values into a MESA_FORAMT_Z24_S8 or MESA_FORMAT_S8_Z24
  504.  * renderbuffer.  No masking, zooming, scaling, etc.
  505.  */
  506. static void
  507. fast_draw_depth_stencil(struct gl_context *ctx, GLint x, GLint y,
  508.                         GLsizei width, GLsizei height,
  509.                         const struct gl_pixelstore_attrib *unpack,
  510.                         const GLvoid *pixels)
  511. {
  512.    const GLenum format = GL_DEPTH_STENCIL_EXT;
  513.    const GLenum type = GL_UNSIGNED_INT_24_8;
  514.    struct gl_renderbuffer *rb =
  515.       ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
  516.    struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
  517.    GLubyte *src, *dst;
  518.    GLint srcRowStride, dstRowStride;
  519.    GLint i;
  520.  
  521.    src = _mesa_image_address2d(unpack, pixels, width, height,
  522.                                format, type, 0, 0);
  523.    srcRowStride = _mesa_image_row_stride(unpack, width, format, type);
  524.  
  525.    dst = _swrast_pixel_address(rb, x, y);
  526.    dstRowStride = srb->RowStride;
  527.  
  528.    for (i = 0; i < height; i++) {
  529.       _mesa_pack_uint_24_8_depth_stencil_row(rb->Format, width,
  530.                                              (const GLuint *) src, dst);
  531.       dst += dstRowStride;
  532.       src += srcRowStride;
  533.    }
  534. }
  535.  
  536.  
  537.  
  538. /**
  539.  * This is a bit different from drawing GL_DEPTH_COMPONENT pixels.
  540.  * The only per-pixel operations that apply are depth scale/bias,
  541.  * stencil offset/shift, GL_DEPTH_WRITEMASK and GL_STENCIL_WRITEMASK,
  542.  * and pixel zoom.
  543.  * Also, only the depth buffer and stencil buffers are touched, not the
  544.  * color buffer(s).
  545.  */
  546. static void
  547. draw_depth_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
  548.                           GLsizei width, GLsizei height, GLenum type,
  549.                           const struct gl_pixelstore_attrib *unpack,
  550.                           const GLvoid *pixels)
  551. {
  552.    const GLint imgX = x, imgY = y;
  553.    const GLboolean scaleOrBias
  554.       = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
  555.    const GLuint stencilMask = ctx->Stencil.WriteMask[0];
  556.    const GLenum stencilType = GL_UNSIGNED_BYTE;
  557.    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
  558.    struct gl_renderbuffer *depthRb, *stencilRb;
  559.    struct gl_pixelstore_attrib clippedUnpack = *unpack;
  560.  
  561.    if (!zoom) {
  562.       if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height,
  563.                                  &clippedUnpack)) {
  564.          /* totally clipped */
  565.          return;
  566.       }
  567.    }
  568.    
  569.    depthRb = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
  570.    stencilRb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
  571.    ASSERT(depthRb);
  572.    ASSERT(stencilRb);
  573.  
  574.    if (depthRb == stencilRb &&
  575.        (depthRb->Format == MESA_FORMAT_Z24_S8 ||
  576.         depthRb->Format == MESA_FORMAT_S8_Z24) &&
  577.        type == GL_UNSIGNED_INT_24_8 &&
  578.        !scaleOrBias &&
  579.        !zoom &&
  580.        ctx->Depth.Mask &&
  581.        (stencilMask & 0xff) == 0xff) {
  582.       fast_draw_depth_stencil(ctx, x, y, width, height,
  583.                               &clippedUnpack, pixels);
  584.    }
  585.    else {
  586.       /* sub-optimal cases:
  587.        * Separate depth/stencil buffers, or pixel transfer ops required.
  588.        */
  589.       /* XXX need to handle very wide images (skippixels) */
  590.       GLuint *zValues;  /* 32-bit Z values */
  591.       GLint i;
  592.  
  593.       zValues = malloc(width * sizeof(GLuint));
  594.       if (!zValues) {
  595.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
  596.          return;
  597.       }
  598.  
  599.       for (i = 0; i < height; i++) {
  600.          const GLuint *depthStencilSrc = (const GLuint *)
  601.             _mesa_image_address2d(&clippedUnpack, pixels, width, height,
  602.                                   GL_DEPTH_STENCIL_EXT, type, i, 0);
  603.  
  604.          if (ctx->Depth.Mask) {
  605.             _mesa_unpack_depth_span(ctx, width,
  606.                                     GL_UNSIGNED_INT, /* dest type */
  607.                                     zValues,         /* dest addr */
  608.                                     0xffffffff,      /* depth max */
  609.                                     type,            /* src type */
  610.                                     depthStencilSrc, /* src addr */
  611.                                     &clippedUnpack);
  612.             if (zoom) {
  613.                _swrast_write_zoomed_z_span(ctx, imgX, imgY, width, x,
  614.                                            y + i, zValues);
  615.             }
  616.             else {
  617.                GLubyte *dst = _swrast_pixel_address(depthRb, x, y + i);
  618.                _mesa_pack_uint_z_row(depthRb->Format, width, zValues, dst);
  619.             }
  620.          }
  621.  
  622.          if (stencilMask != 0x0) {
  623.             GLubyte *stencilValues = (GLubyte *) zValues; /* re-use buffer */
  624.             /* get stencil values, with shift/offset/mapping */
  625.             _mesa_unpack_stencil_span(ctx, width, stencilType, stencilValues,
  626.                                       type, depthStencilSrc, &clippedUnpack,
  627.                                       ctx->_ImageTransferState);
  628.             if (zoom)
  629.                _swrast_write_zoomed_stencil_span(ctx, imgX, imgY, width,
  630.                                                   x, y + i, stencilValues);
  631.             else
  632.                _swrast_write_stencil_span(ctx, width, x, y + i, stencilValues);
  633.          }
  634.       }
  635.  
  636.       free(zValues);
  637.    }
  638. }
  639.  
  640.  
  641. /**
  642.  * Execute software-based glDrawPixels.
  643.  * By time we get here, all error checking will have been done.
  644.  */
  645. void
  646. _swrast_DrawPixels( struct gl_context *ctx,
  647.                     GLint x, GLint y,
  648.                     GLsizei width, GLsizei height,
  649.                     GLenum format, GLenum type,
  650.                     const struct gl_pixelstore_attrib *unpack,
  651.                     const GLvoid *pixels )
  652. {
  653.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  654.    GLboolean save_vp_override = ctx->VertexProgram._Overriden;
  655.  
  656.    if (!_mesa_check_conditional_render(ctx))
  657.       return; /* don't draw */
  658.  
  659.    /* We are creating fragments directly, without going through vertex
  660.     * programs.
  661.     *
  662.     * This override flag tells the fragment processing code that its input
  663.     * comes from a non-standard source, and it may therefore not rely on
  664.     * optimizations that assume e.g. constant color if there is no color
  665.     * vertex array.
  666.     */
  667.    _mesa_set_vp_override(ctx, GL_TRUE);
  668.  
  669.    if (ctx->NewState)
  670.       _mesa_update_state(ctx);
  671.  
  672.    if (swrast->NewState)
  673.       _swrast_validate_derived( ctx );
  674.  
  675.    pixels = _mesa_map_pbo_source(ctx, unpack, pixels);
  676.    if (!pixels) {
  677.       _mesa_set_vp_override(ctx, save_vp_override);
  678.       return;
  679.    }
  680.  
  681.    /*
  682.     * By time we get here, all error checking should have been done.
  683.     */
  684.    switch (format) {
  685.    case GL_STENCIL_INDEX:
  686.       swrast_render_start(ctx);
  687.       draw_stencil_pixels( ctx, x, y, width, height, type, unpack, pixels );
  688.       swrast_render_finish(ctx);
  689.       break;
  690.    case GL_DEPTH_COMPONENT:
  691.       swrast_render_start(ctx);
  692.       draw_depth_pixels( ctx, x, y, width, height, type, unpack, pixels );
  693.       swrast_render_finish(ctx);
  694.       break;
  695.    case GL_DEPTH_STENCIL_EXT:
  696.       swrast_render_start(ctx);
  697.       draw_depth_stencil_pixels(ctx, x, y, width, height, type, unpack, pixels);
  698.       swrast_render_finish(ctx);
  699.       break;
  700.    default:
  701.       /* all other formats should be color formats */
  702.       draw_rgba_pixels(ctx, x, y, width, height, format, type, unpack, pixels);
  703.    }
  704.  
  705.    _mesa_set_vp_override(ctx, save_vp_override);
  706.  
  707.    _mesa_unmap_pbo_source(ctx, unpack);
  708. }
  709.