Subversion Repositories Kolibri OS

Rev

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