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-2008  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/context.h"
  28. #include "main/formats.h"
  29. #include "main/format_unpack.h"
  30. #include "main/format_pack.h"
  31. #include "main/macros.h"
  32. #include "main/imports.h"
  33.  
  34. #include "s_context.h"
  35. #include "s_depth.h"
  36. #include "s_span.h"
  37.  
  38.  
  39.  
  40. #define Z_TEST(COMPARE)                      \
  41.    do {                                      \
  42.       GLuint i;                              \
  43.       for (i = 0; i < n; i++) {              \
  44.          if (mask[i]) {                      \
  45.             if (COMPARE) {                   \
  46.                /* pass */                    \
  47.                if (write) {                  \
  48.                   zbuffer[i] = zfrag[i];     \
  49.                }                             \
  50.                passed++;                     \
  51.             }                                \
  52.             else {                           \
  53.                /* fail */                    \
  54.                mask[i] = 0;                  \
  55.             }                                \
  56.          }                                   \
  57.       }                                      \
  58.    } while (0)
  59.  
  60.  
  61. /**
  62.  * Do depth test for an array of 16-bit Z values.
  63.  * @param zbuffer  array of Z buffer values (16-bit)
  64.  * @param zfrag  array of fragment Z values (use 16-bit in 32-bit uint)
  65.  * @param mask  which fragments are alive, killed afterward
  66.  * @return  number of fragments which pass the test.
  67.  */
  68. static GLuint
  69. depth_test_span16( struct gl_context *ctx, GLuint n,
  70.                    GLushort zbuffer[], const GLuint zfrag[], GLubyte mask[] )
  71. {
  72.    const GLboolean write = ctx->Depth.Mask;
  73.    GLuint passed = 0;
  74.  
  75.    /* switch cases ordered from most frequent to less frequent */
  76.    switch (ctx->Depth.Func) {
  77.    case GL_LESS:
  78.       Z_TEST(zfrag[i] < zbuffer[i]);
  79.       break;
  80.    case GL_LEQUAL:
  81.       Z_TEST(zfrag[i] <= zbuffer[i]);
  82.       break;
  83.    case GL_GEQUAL:
  84.       Z_TEST(zfrag[i] >= zbuffer[i]);
  85.       break;
  86.    case GL_GREATER:
  87.       Z_TEST(zfrag[i] > zbuffer[i]);
  88.       break;
  89.    case GL_NOTEQUAL:
  90.       Z_TEST(zfrag[i] != zbuffer[i]);
  91.       break;
  92.    case GL_EQUAL:
  93.       Z_TEST(zfrag[i] == zbuffer[i]);
  94.       break;
  95.    case GL_ALWAYS:
  96.       Z_TEST(1);
  97.       break;
  98.    case GL_NEVER:
  99.       memset(mask, 0, n * sizeof(GLubyte));
  100.       break;
  101.    default:
  102.       _mesa_problem(ctx, "Bad depth func in depth_test_span16");
  103.    }
  104.  
  105.    return passed;
  106. }
  107.  
  108.  
  109. /**
  110.  * Do depth test for an array of 32-bit Z values.
  111.  * @param zbuffer  array of Z buffer values (32-bit)
  112.  * @param zfrag  array of fragment Z values (use 32-bits in 32-bit uint)
  113.  * @param mask  which fragments are alive, killed afterward
  114.  * @return  number of fragments which pass the test.
  115.  */
  116. static GLuint
  117. depth_test_span32( struct gl_context *ctx, GLuint n,
  118.                    GLuint zbuffer[], const GLuint zfrag[], GLubyte mask[])
  119. {
  120.    const GLboolean write = ctx->Depth.Mask;
  121.    GLuint passed = 0;
  122.  
  123.    /* switch cases ordered from most frequent to less frequent */
  124.    switch (ctx->Depth.Func) {
  125.    case GL_LESS:
  126.       Z_TEST(zfrag[i] < zbuffer[i]);
  127.       break;
  128.    case GL_LEQUAL:
  129.       Z_TEST(zfrag[i] <= zbuffer[i]);
  130.       break;
  131.    case GL_GEQUAL:
  132.       Z_TEST(zfrag[i] >= zbuffer[i]);
  133.       break;
  134.    case GL_GREATER:
  135.       Z_TEST(zfrag[i] > zbuffer[i]);
  136.       break;
  137.    case GL_NOTEQUAL:
  138.       Z_TEST(zfrag[i] != zbuffer[i]);
  139.       break;
  140.    case GL_EQUAL:
  141.       Z_TEST(zfrag[i] == zbuffer[i]);
  142.       break;
  143.    case GL_ALWAYS:
  144.       Z_TEST(1);
  145.       break;
  146.    case GL_NEVER:
  147.       memset(mask, 0, n * sizeof(GLubyte));
  148.       break;
  149.    default:
  150.       _mesa_problem(ctx, "Bad depth func in depth_test_span32");
  151.    }
  152.  
  153.    return passed;
  154. }
  155.  
  156.  
  157. /**
  158.  * Clamp fragment Z values to the depth near/far range (glDepthRange()).
  159.  * This is used when GL_ARB_depth_clamp/GL_DEPTH_CLAMP is turned on.
  160.  * In that case, vertexes are not clipped against the near/far planes
  161.  * so rasterization will produce fragment Z values outside the usual
  162.  * [0,1] range.
  163.  */
  164. void
  165. _swrast_depth_clamp_span( struct gl_context *ctx, SWspan *span )
  166. {
  167.    struct gl_framebuffer *fb = ctx->DrawBuffer;
  168.    const GLuint count = span->end;
  169.    GLint *zValues = (GLint *) span->array->z; /* sign change */
  170.    GLint min, max;
  171.    GLfloat min_f, max_f;
  172.    GLuint i;
  173.  
  174.    if (ctx->Viewport.Near < ctx->Viewport.Far) {
  175.       min_f = ctx->Viewport.Near;
  176.       max_f = ctx->Viewport.Far;
  177.    } else {
  178.       min_f = ctx->Viewport.Far;
  179.       max_f = ctx->Viewport.Near;
  180.    }
  181.  
  182.    /* Convert floating point values in [0,1] to device Z coordinates in
  183.     * [0, DepthMax].
  184.     * ex: If the Z buffer has 24 bits, DepthMax = 0xffffff.
  185.     *
  186.     * XXX this all falls apart if we have 31 or more bits of Z because
  187.     * the triangle rasterization code produces unsigned Z values.  Negative
  188.     * vertex Z values come out as large fragment Z uints.
  189.     */
  190.    min = (GLint) (min_f * fb->_DepthMaxF);
  191.    max = (GLint) (max_f * fb->_DepthMaxF);
  192.    if (max < 0)
  193.       max = 0x7fffffff; /* catch over flow for 30-bit z */
  194.  
  195.    /* Note that we do the comparisons here using signed integers.
  196.     */
  197.    for (i = 0; i < count; i++) {
  198.       if (zValues[i] < min)
  199.          zValues[i] = min;
  200.       if (zValues[i] > max)
  201.          zValues[i] = max;
  202.    }
  203. }
  204.  
  205.  
  206. /**
  207.  * Get array of 32-bit z values from the depth buffer.  With clipping.
  208.  * Note: the returned values are always in the range [0, 2^32-1].
  209.  */
  210. static void
  211. get_z32_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
  212.                GLuint count, const GLint x[], const GLint y[],
  213.                GLuint zbuffer[])
  214. {
  215.    struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
  216.    const GLint w = rb->Width, h = rb->Height;
  217.    const GLubyte *map = _swrast_pixel_address(rb, 0, 0);
  218.    GLuint i;
  219.  
  220.    if (rb->Format == MESA_FORMAT_Z32) {
  221.       const GLint rowStride = srb->RowStride;
  222.       for (i = 0; i < count; i++) {
  223.          if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
  224.             zbuffer[i] = *((GLuint *) (map + y[i] * rowStride + x[i] * 4));
  225.          }
  226.       }
  227.    }
  228.    else {
  229.       const GLint bpp = _mesa_get_format_bytes(rb->Format);
  230.       const GLint rowStride = srb->RowStride;
  231.       for (i = 0; i < count; i++) {
  232.          if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
  233.             const GLubyte *src = map + y[i] * rowStride+ x[i] * bpp;
  234.             _mesa_unpack_uint_z_row(rb->Format, 1, src, &zbuffer[i]);
  235.          }
  236.       }
  237.    }
  238. }
  239.  
  240.  
  241. /**
  242.  * Put an array of 32-bit z values into the depth buffer.
  243.  * Note: the z values are always in the range [0, 2^32-1].
  244.  */
  245. static void
  246. put_z32_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
  247.                GLuint count, const GLint x[], const GLint y[],
  248.                const GLuint zvalues[], const GLubyte mask[])
  249. {
  250.    struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
  251.    const GLint w = rb->Width, h = rb->Height;
  252.    GLubyte *map = _swrast_pixel_address(rb, 0, 0);
  253.    GLuint i;
  254.  
  255.    if (rb->Format == MESA_FORMAT_Z32) {
  256.       const GLint rowStride = srb->RowStride;
  257.       for (i = 0; i < count; i++) {
  258.          if (mask[i] && x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
  259.             GLuint *dst = (GLuint *) (map + y[i] * rowStride + x[i] * 4);
  260.             *dst = zvalues[i];
  261.          }
  262.       }
  263.    }
  264.    else {
  265.       gl_pack_uint_z_func packZ = _mesa_get_pack_uint_z_func(rb->Format);
  266.       const GLint bpp = _mesa_get_format_bytes(rb->Format);
  267.       const GLint rowStride = srb->RowStride;
  268.       for (i = 0; i < count; i++) {
  269.          if (mask[i] && x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
  270.             void *dst = map + y[i] * rowStride + x[i] * bpp;
  271.             packZ(zvalues + i, dst);
  272.          }
  273.       }
  274.    }
  275. }
  276.  
  277.  
  278. /**
  279.  * Apply depth (Z) buffer testing to the span.
  280.  * \return approx number of pixels that passed (only zero is reliable)
  281.  */
  282. GLuint
  283. _swrast_depth_test_span(struct gl_context *ctx, SWspan *span)
  284. {
  285.    struct gl_framebuffer *fb = ctx->DrawBuffer;
  286.    struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
  287.    const GLint bpp = _mesa_get_format_bytes(rb->Format);
  288.    void *zStart;
  289.    const GLuint count = span->end;
  290.    const GLuint *fragZ = span->array->z;
  291.    GLubyte *mask = span->array->mask;
  292.    void *zBufferVals;
  293.    GLuint *zBufferTemp = NULL;
  294.    GLuint passed;
  295.    GLuint zBits = _mesa_get_format_bits(rb->Format, GL_DEPTH_BITS);
  296.    GLboolean ztest16 = GL_FALSE;
  297.  
  298.    if (span->arrayMask & SPAN_XY)
  299.       zStart = NULL;
  300.    else
  301.       zStart = _swrast_pixel_address(rb, span->x, span->y);
  302.  
  303.    if (rb->Format == MESA_FORMAT_Z16 && !(span->arrayMask & SPAN_XY)) {
  304.       /* directly read/write row of 16-bit Z values */
  305.       zBufferVals = zStart;
  306.       ztest16 = GL_TRUE;
  307.    }
  308.    else if (rb->Format == MESA_FORMAT_Z32 && !(span->arrayMask & SPAN_XY)) {
  309.       /* directly read/write row of 32-bit Z values */
  310.       zBufferVals = zStart;
  311.    }
  312.    else {
  313.       if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_NORMALIZED) {
  314.          _mesa_problem(ctx, "Incorrectly writing swrast's integer depth "
  315.                        "values to %s depth buffer",
  316.                        _mesa_get_format_name(rb->Format));
  317.       }
  318.  
  319.       /* copy Z buffer values into temp buffer (32-bit Z values) */
  320.       zBufferTemp = malloc(count * sizeof(GLuint));
  321.       if (!zBufferTemp)
  322.          return 0;
  323.  
  324.       if (span->arrayMask & SPAN_XY) {
  325.          get_z32_values(ctx, rb, count,
  326.                         span->array->x, span->array->y, zBufferTemp);
  327.       }
  328.       else {
  329.          _mesa_unpack_uint_z_row(rb->Format, count, zStart, zBufferTemp);
  330.       }
  331.  
  332.       if (zBits == 24) {
  333.          GLuint i;
  334.          /* Convert depth buffer values from 32 to 24 bits to match the
  335.           * fragment Z values generated by rasterization.
  336.           */
  337.          for (i = 0; i < count; i++) {
  338.             zBufferTemp[i] >>= 8;
  339.          }
  340.       }
  341.       else if (zBits == 16) {
  342.          GLuint i;
  343.          /* Convert depth buffer values from 32 to 16 bits */
  344.          for (i = 0; i < count; i++) {
  345.             zBufferTemp[i] >>= 16;
  346.          }
  347.       }
  348.       else {
  349.          assert(zBits == 32);
  350.       }
  351.  
  352.       zBufferVals = zBufferTemp;
  353.    }
  354.  
  355.    /* do the depth test either with 16 or 32-bit values */
  356.    if (ztest16)
  357.       passed = depth_test_span16(ctx, count, zBufferVals, fragZ, mask);
  358.    else
  359.       passed = depth_test_span32(ctx, count, zBufferVals, fragZ, mask);
  360.  
  361.    if (zBufferTemp) {
  362.       /* need to write temp Z values back into the buffer */
  363.  
  364.       /* Convert depth buffer values back to 32-bit values.  The least
  365.        * significant bits don't matter since they'll get dropped when
  366.        * they're packed back into the depth buffer.
  367.        */
  368.       if (zBits == 24) {
  369.          GLuint i;
  370.          for (i = 0; i < count; i++) {
  371.             zBufferTemp[i] = (zBufferTemp[i] << 8);
  372.          }
  373.       }
  374.       else if (zBits == 16) {
  375.          GLuint i;
  376.          for (i = 0; i < count; i++) {
  377.             zBufferTemp[i] = zBufferTemp[i] << 16;
  378.          }
  379.       }
  380.  
  381.       if (span->arrayMask & SPAN_XY) {
  382.          /* random locations */
  383.          put_z32_values(ctx, rb, count, span->array->x, span->array->y,
  384.                         zBufferTemp, mask);
  385.       }
  386.       else {
  387.          /* horizontal row */
  388.          gl_pack_uint_z_func packZ = _mesa_get_pack_uint_z_func(rb->Format);
  389.          GLubyte *dst = zStart;
  390.          GLuint i;
  391.          for (i = 0; i < count; i++) {
  392.             if (mask[i]) {
  393.                packZ(&zBufferTemp[i], dst);
  394.             }
  395.             dst += bpp;
  396.          }
  397.       }
  398.  
  399.       free(zBufferTemp);
  400.    }
  401.  
  402.    if (passed < count) {
  403.       span->writeAll = GL_FALSE;
  404.    }
  405.    return passed;
  406. }
  407.  
  408.  
  409. /**
  410.  * GL_EXT_depth_bounds_test extension.
  411.  * Discard fragments depending on whether the corresponding Z-buffer
  412.  * values are outside the depth bounds test range.
  413.  * Note: we test the Z buffer values, not the fragment Z values!
  414.  * \return GL_TRUE if any fragments pass, GL_FALSE if no fragments pass
  415.  */
  416. GLboolean
  417. _swrast_depth_bounds_test( struct gl_context *ctx, SWspan *span )
  418. {
  419.    struct gl_framebuffer *fb = ctx->DrawBuffer;
  420.    struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
  421.    GLubyte *zStart;
  422.    GLuint zMin = (GLuint) (ctx->Depth.BoundsMin * fb->_DepthMaxF + 0.5F);
  423.    GLuint zMax = (GLuint) (ctx->Depth.BoundsMax * fb->_DepthMaxF + 0.5F);
  424.    GLubyte *mask = span->array->mask;
  425.    const GLuint count = span->end;
  426.    GLuint i;
  427.    GLboolean anyPass = GL_FALSE;
  428.    GLuint *zBufferTemp;
  429.    const GLuint *zBufferVals;
  430.  
  431.    zBufferTemp = malloc(count * sizeof(GLuint));
  432.    if (!zBufferTemp) {
  433.       /* don't generate a stream of OUT_OF_MEMORY errors here */
  434.       return GL_FALSE;
  435.    }
  436.  
  437.    if (span->arrayMask & SPAN_XY)
  438.       zStart = NULL;
  439.    else
  440.       zStart = _swrast_pixel_address(rb, span->x, span->y);
  441.  
  442.    if (rb->Format == MESA_FORMAT_Z32 && !(span->arrayMask & SPAN_XY)) {
  443.       /* directly access 32-bit values in the depth buffer */
  444.       zBufferVals = (const GLuint *) zStart;
  445.    }
  446.    else {
  447.       /* unpack Z values into a temporary array */
  448.       if (span->arrayMask & SPAN_XY) {
  449.          get_z32_values(ctx, rb, count, span->array->x, span->array->y,
  450.                         zBufferTemp);
  451.       }
  452.       else {
  453.          _mesa_unpack_uint_z_row(rb->Format, count, zStart, zBufferTemp);
  454.       }
  455.       zBufferVals = zBufferTemp;
  456.    }
  457.  
  458.    /* Now do the tests */
  459.    for (i = 0; i < count; i++) {
  460.       if (mask[i]) {
  461.          if (zBufferVals[i] < zMin || zBufferVals[i] > zMax)
  462.             mask[i] = GL_FALSE;
  463.          else
  464.             anyPass = GL_TRUE;
  465.       }
  466.    }
  467.  
  468.    free(zBufferTemp);
  469.  
  470.    return anyPass;
  471. }
  472.  
  473.  
  474.  
  475. /**********************************************************************/
  476. /*****                      Read Depth Buffer                     *****/
  477. /**********************************************************************/
  478.  
  479.  
  480. /**
  481.  * Read a span of depth values from the given depth renderbuffer, returning
  482.  * the values as GLfloats.
  483.  * This function does clipping to prevent reading outside the depth buffer's
  484.  * bounds.
  485.  */
  486. void
  487. _swrast_read_depth_span_float(struct gl_context *ctx,
  488.                               struct gl_renderbuffer *rb,
  489.                               GLint n, GLint x, GLint y, GLfloat depth[])
  490. {
  491.    if (!rb) {
  492.       /* really only doing this to prevent FP exceptions later */
  493.       memset(depth, 0, n * sizeof(GLfloat));
  494.       return;
  495.    }
  496.  
  497.    if (y < 0 || y >= (GLint) rb->Height ||
  498.        x + n <= 0 || x >= (GLint) rb->Width) {
  499.       /* span is completely outside framebuffer */
  500.       memset(depth, 0, n * sizeof(GLfloat));
  501.       return;
  502.    }
  503.  
  504.    if (x < 0) {
  505.       GLint dx = -x;
  506.       GLint i;
  507.       for (i = 0; i < dx; i++)
  508.          depth[i] = 0.0;
  509.       x = 0;
  510.       n -= dx;
  511.       depth += dx;
  512.    }
  513.    if (x + n > (GLint) rb->Width) {
  514.       GLint dx = x + n - (GLint) rb->Width;
  515.       GLint i;
  516.       for (i = 0; i < dx; i++)
  517.          depth[n - i - 1] = 0.0;
  518.       n -= dx;
  519.    }
  520.    if (n <= 0) {
  521.       return;
  522.    }
  523.  
  524.    _mesa_unpack_float_z_row(rb->Format, n, _swrast_pixel_address(rb, x, y),
  525.                             depth);
  526. }
  527.  
  528.  
  529. /**
  530.  * Clear the given z/depth renderbuffer.  If the buffer is a combined
  531.  * depth+stencil buffer, only the Z bits will be touched.
  532.  */
  533. void
  534. _swrast_clear_depth_buffer(struct gl_context *ctx)
  535. {
  536.    struct gl_renderbuffer *rb =
  537.       ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
  538.    GLint x, y, width, height;
  539.    GLubyte *map;
  540.    GLint rowStride, i, j;
  541.    GLbitfield mapMode;
  542.  
  543.    if (!rb || !ctx->Depth.Mask) {
  544.       /* no depth buffer, or writing to it is disabled */
  545.       return;
  546.    }
  547.  
  548.    /* compute region to clear */
  549.    x = ctx->DrawBuffer->_Xmin;
  550.    y = ctx->DrawBuffer->_Ymin;
  551.    width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
  552.    height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
  553.  
  554.    mapMode = GL_MAP_WRITE_BIT;
  555.    if (rb->Format == MESA_FORMAT_S8_Z24 ||
  556.        rb->Format == MESA_FORMAT_X8_Z24 ||
  557.        rb->Format == MESA_FORMAT_Z24_S8 ||
  558.        rb->Format == MESA_FORMAT_Z24_X8) {
  559.       mapMode |= GL_MAP_READ_BIT;
  560.    }
  561.  
  562.    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
  563.                                mapMode, &map, &rowStride);
  564.    if (!map) {
  565.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(depth)");
  566.       return;
  567.    }
  568.  
  569.    switch (rb->Format) {
  570.    case MESA_FORMAT_Z16:
  571.       {
  572.          GLfloat clear = (GLfloat) ctx->Depth.Clear;
  573.          GLushort clearVal = 0;
  574.          _mesa_pack_float_z_row(rb->Format, 1, &clear, &clearVal);
  575.          if (clearVal == 0xffff && width * 2 == rowStride) {
  576.             /* common case */
  577.             memset(map, 0xff, width * height * 2);
  578.          }
  579.          else {
  580.             for (i = 0; i < height; i++) {
  581.                GLushort *row = (GLushort *) map;
  582.                for (j = 0; j < width; j++) {
  583.                   row[j] = clearVal;
  584.                }
  585.                map += rowStride;
  586.             }
  587.          }
  588.       }
  589.       break;
  590.    case MESA_FORMAT_Z32:
  591.    case MESA_FORMAT_Z32_FLOAT:
  592.       {
  593.          GLfloat clear = (GLfloat) ctx->Depth.Clear;
  594.          GLuint clearVal = 0;
  595.          _mesa_pack_float_z_row(rb->Format, 1, &clear, &clearVal);
  596.          for (i = 0; i < height; i++) {
  597.             GLuint *row = (GLuint *) map;
  598.             for (j = 0; j < width; j++) {
  599.                row[j] = clearVal;
  600.             }
  601.             map += rowStride;
  602.          }
  603.       }
  604.       break;
  605.    case MESA_FORMAT_S8_Z24:
  606.    case MESA_FORMAT_X8_Z24:
  607.    case MESA_FORMAT_Z24_S8:
  608.    case MESA_FORMAT_Z24_X8:
  609.       {
  610.          GLfloat clear = (GLfloat) ctx->Depth.Clear;
  611.          GLuint clearVal = 0;
  612.          GLuint mask;
  613.  
  614.          if (rb->Format == MESA_FORMAT_S8_Z24 ||
  615.              rb->Format == MESA_FORMAT_X8_Z24)
  616.             mask = 0xff000000;
  617.          else
  618.             mask = 0xff;
  619.  
  620.          _mesa_pack_float_z_row(rb->Format, 1, &clear, &clearVal);
  621.          for (i = 0; i < height; i++) {
  622.             GLuint *row = (GLuint *) map;
  623.             for (j = 0; j < width; j++) {
  624.                row[j] = (row[j] & mask) | clearVal;
  625.             }
  626.             map += rowStride;
  627.          }
  628.  
  629.       }
  630.       break;
  631.    case MESA_FORMAT_Z32_FLOAT_X24S8:
  632.       /* XXX untested */
  633.       {
  634.          GLfloat clearVal = (GLfloat) ctx->Depth.Clear;
  635.          for (i = 0; i < height; i++) {
  636.             GLfloat *row = (GLfloat *) map;
  637.             for (j = 0; j < width; j++) {
  638.                row[j * 2] = clearVal;
  639.             }
  640.             map += rowStride;
  641.          }
  642.       }
  643.       break;
  644.    default:
  645.       _mesa_problem(ctx, "Unexpected depth buffer format %s"
  646.                     " in _swrast_clear_depth_buffer()",
  647.                     _mesa_get_format_name(rb->Format));
  648.    }
  649.  
  650.    ctx->Driver.UnmapRenderbuffer(ctx, rb);
  651. }
  652.  
  653.  
  654.  
  655.  
  656. /**
  657.  * Clear both depth and stencil values in a combined depth+stencil buffer.
  658.  */
  659. void
  660. _swrast_clear_depth_stencil_buffer(struct gl_context *ctx)
  661. {
  662.    const GLubyte stencilBits = ctx->DrawBuffer->Visual.stencilBits;
  663.    const GLuint writeMask = ctx->Stencil.WriteMask[0];
  664.    const GLuint stencilMax = (1 << stencilBits) - 1;
  665.    struct gl_renderbuffer *rb =
  666.       ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
  667.    GLint x, y, width, height;
  668.    GLbitfield mapMode;
  669.    GLubyte *map;
  670.    GLint rowStride, i, j;
  671.  
  672.    /* check that we really have a combined depth+stencil buffer */
  673.    assert(rb == ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer);
  674.  
  675.    /* compute region to clear */
  676.    x = ctx->DrawBuffer->_Xmin;
  677.    y = ctx->DrawBuffer->_Ymin;
  678.    width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
  679.    height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
  680.  
  681.    mapMode = GL_MAP_WRITE_BIT;
  682.    if ((writeMask & stencilMax) != stencilMax) {
  683.       /* need to mask stencil values */
  684.       mapMode |= GL_MAP_READ_BIT;
  685.    }
  686.  
  687.    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
  688.                                mapMode, &map, &rowStride);
  689.    if (!map) {
  690.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(depth+stencil)");
  691.       return;
  692.    }
  693.  
  694.    switch (rb->Format) {
  695.    case MESA_FORMAT_S8_Z24:
  696.    case MESA_FORMAT_Z24_S8:
  697.       {
  698.          GLfloat zClear = (GLfloat) ctx->Depth.Clear;
  699.          GLuint clear = 0, mask;
  700.  
  701.          _mesa_pack_float_z_row(rb->Format, 1, &zClear, &clear);
  702.  
  703.          if (rb->Format == MESA_FORMAT_S8_Z24) {
  704.             mask = ((~writeMask) & 0xff) << 24;
  705.             clear |= (ctx->Stencil.Clear & writeMask & 0xff) << 24;
  706.          }
  707.          else {
  708.             mask = ((~writeMask) & 0xff);
  709.             clear |= (ctx->Stencil.Clear & writeMask & 0xff);
  710.          }
  711.  
  712.          for (i = 0; i < height; i++) {
  713.             GLuint *row = (GLuint *) map;
  714.             if (mask != 0x0) {
  715.                for (j = 0; j < width; j++) {
  716.                   row[j] = (row[j] & mask) | clear;
  717.                }
  718.             }
  719.             else {
  720.                for (j = 0; j < width; j++) {
  721.                   row[j] = clear;
  722.                }
  723.             }
  724.             map += rowStride;
  725.          }
  726.       }
  727.       break;
  728.    case MESA_FORMAT_Z32_FLOAT_X24S8:
  729.       /* XXX untested */
  730.       {
  731.          const GLfloat zClear = (GLfloat) ctx->Depth.Clear;
  732.          const GLuint sClear = ctx->Stencil.Clear & writeMask;
  733.          const GLuint sMask = (~writeMask) & 0xff;
  734.          for (i = 0; i < height; i++) {
  735.             GLfloat *zRow = (GLfloat *) map;
  736.             GLuint *sRow = (GLuint *) map;
  737.             for (j = 0; j < width; j++) {
  738.                zRow[j * 2 + 0] = zClear;
  739.             }
  740.             if (sMask != 0) {
  741.                for (j = 0; j < width; j++) {
  742.                   sRow[j * 2 + 1] = (sRow[j * 2 + 1] & sMask) | sClear;
  743.                }
  744.             }
  745.             else {
  746.                for (j = 0; j < width; j++) {
  747.                   sRow[j * 2 + 1] = sClear;
  748.                }
  749.             }
  750.             map += rowStride;
  751.          }
  752.       }
  753.       break;
  754.    default:
  755.       _mesa_problem(ctx, "Unexpected depth buffer format %s"
  756.                     " in _swrast_clear_depth_buffer()",
  757.                     _mesa_get_format_name(rb->Format));
  758.    }
  759.  
  760.    ctx->Driver.UnmapRenderbuffer(ctx, rb);
  761.  
  762. }
  763.