Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Mesa 3-D graphics library
  3.  * Version:  7.2.1
  4.  *
  5.  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included
  15.  * in all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  21.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25.  
  26. #include "main/glheader.h"
  27. #include "main/context.h"
  28. #include "main/formats.h"
  29. #include "main/macros.h"
  30. #include "main/imports.h"
  31.  
  32. #include "s_depth.h"
  33. #include "s_span.h"
  34.  
  35.  
  36. /**
  37.  * Do depth test for a horizontal span of fragments.
  38.  * Input:  zbuffer - array of z values in the zbuffer
  39.  *         z - array of fragment z values
  40.  * Return:  number of fragments which pass the test.
  41.  */
  42. static GLuint
  43. depth_test_span16( struct gl_context *ctx, GLuint n,
  44.                    GLushort zbuffer[], const GLuint z[], GLubyte mask[] )
  45. {
  46.    GLuint passed = 0;
  47.  
  48.    /* switch cases ordered from most frequent to less frequent */
  49.    switch (ctx->Depth.Func) {
  50.       case GL_LESS:
  51.          if (ctx->Depth.Mask) {
  52.             /* Update Z buffer */
  53.             GLuint i;
  54.             for (i=0; i<n; i++) {
  55.                if (mask[i]) {
  56.                   if (z[i] < zbuffer[i]) {
  57.                      /* pass */
  58.                      zbuffer[i] = z[i];
  59.                      passed++;
  60.                   }
  61.                   else {
  62.                      /* fail */
  63.                      mask[i] = 0;
  64.                   }
  65.                }
  66.             }
  67.          }
  68.          else {
  69.             /* Don't update Z buffer */
  70.             GLuint i;
  71.             for (i=0; i<n; i++) {
  72.                if (mask[i]) {
  73.                   if (z[i] < zbuffer[i]) {
  74.                      /* pass */
  75.                      passed++;
  76.                   }
  77.                   else {
  78.                      mask[i] = 0;
  79.                   }
  80.                }
  81.             }
  82.          }
  83.          break;
  84.       case GL_LEQUAL:
  85.          if (ctx->Depth.Mask) {
  86.             /* Update Z buffer */
  87.             GLuint i;
  88.             for (i=0;i<n;i++) {
  89.                if (mask[i]) {
  90.                   if (z[i] <= zbuffer[i]) {
  91.                      zbuffer[i] = z[i];
  92.                      passed++;
  93.                   }
  94.                   else {
  95.                      mask[i] = 0;
  96.                   }
  97.                }
  98.             }
  99.          }
  100.          else {
  101.             /* Don't update Z buffer */
  102.             GLuint i;
  103.             for (i=0;i<n;i++) {
  104.                if (mask[i]) {
  105.                   if (z[i] <= zbuffer[i]) {
  106.                      /* pass */
  107.                      passed++;
  108.                   }
  109.                   else {
  110.                      mask[i] = 0;
  111.                   }
  112.                }
  113.             }
  114.          }
  115.          break;
  116.       case GL_GEQUAL:
  117.          if (ctx->Depth.Mask) {
  118.             /* Update Z buffer */
  119.             GLuint i;
  120.             for (i=0;i<n;i++) {
  121.                if (mask[i]) {
  122.                   if (z[i] >= zbuffer[i]) {
  123.                      zbuffer[i] = z[i];
  124.                      passed++;
  125.                   }
  126.                   else {
  127.                      mask[i] = 0;
  128.                   }
  129.                }
  130.             }
  131.          }
  132.          else {
  133.             /* Don't update Z buffer */
  134.             GLuint i;
  135.             for (i=0;i<n;i++) {
  136.                if (mask[i]) {
  137.                   if (z[i] >= zbuffer[i]) {
  138.                      /* pass */
  139.                      passed++;
  140.                   }
  141.                   else {
  142.                      mask[i] = 0;
  143.                   }
  144.                }
  145.             }
  146.          }
  147.          break;
  148.       case GL_GREATER:
  149.          if (ctx->Depth.Mask) {
  150.             /* Update Z buffer */
  151.             GLuint i;
  152.             for (i=0;i<n;i++) {
  153.                if (mask[i]) {
  154.                   if (z[i] > zbuffer[i]) {
  155.                      zbuffer[i] = z[i];
  156.                      passed++;
  157.                   }
  158.                   else {
  159.                      mask[i] = 0;
  160.                   }
  161.                }
  162.             }
  163.          }
  164.          else {
  165.             /* Don't update Z buffer */
  166.             GLuint i;
  167.             for (i=0;i<n;i++) {
  168.                if (mask[i]) {
  169.                   if (z[i] > zbuffer[i]) {
  170.                      /* pass */
  171.                      passed++;
  172.                   }
  173.                   else {
  174.                      mask[i] = 0;
  175.                   }
  176.                }
  177.             }
  178.          }
  179.          break;
  180.       case GL_NOTEQUAL:
  181.          if (ctx->Depth.Mask) {
  182.             /* Update Z buffer */
  183.             GLuint i;
  184.             for (i=0;i<n;i++) {
  185.                if (mask[i]) {
  186.                   if (z[i] != zbuffer[i]) {
  187.                      zbuffer[i] = z[i];
  188.                      passed++;
  189.                   }
  190.                   else {
  191.                      mask[i] = 0;
  192.                   }
  193.                }
  194.             }
  195.          }
  196.          else {
  197.             /* Don't update Z buffer */
  198.             GLuint i;
  199.             for (i=0;i<n;i++) {
  200.                if (mask[i]) {
  201.                   if (z[i] != zbuffer[i]) {
  202.                      /* pass */
  203.                      passed++;
  204.                   }
  205.                   else {
  206.                      mask[i] = 0;
  207.                   }
  208.                }
  209.             }
  210.          }
  211.          break;
  212.       case GL_EQUAL:
  213.          if (ctx->Depth.Mask) {
  214.             /* Update Z buffer */
  215.             GLuint i;
  216.             for (i=0;i<n;i++) {
  217.                if (mask[i]) {
  218.                   if (z[i] == zbuffer[i]) {
  219.                      zbuffer[i] = z[i];
  220.                      passed++;
  221.                   }
  222.                   else {
  223.                      mask[i] = 0;
  224.                   }
  225.                }
  226.             }
  227.          }
  228.          else {
  229.             /* Don't update Z buffer */
  230.             GLuint i;
  231.             for (i=0;i<n;i++) {
  232.                if (mask[i]) {
  233.                   if (z[i] == zbuffer[i]) {
  234.                      /* pass */
  235.                      passed++;
  236.                   }
  237.                   else {
  238.                      mask[i] = 0;
  239.                   }
  240.                }
  241.             }
  242.          }
  243.          break;
  244.       case GL_ALWAYS:
  245.          if (ctx->Depth.Mask) {
  246.             /* Update Z buffer */
  247.             GLuint i;
  248.             for (i=0;i<n;i++) {
  249.                if (mask[i]) {
  250.                   zbuffer[i] = z[i];
  251.                   passed++;
  252.                }
  253.             }
  254.          }
  255.          else {
  256.             /* Don't update Z buffer or mask */
  257.             passed = n;
  258.          }
  259.          break;
  260.       case GL_NEVER:
  261.          memset(mask, 0, n * sizeof(GLubyte));
  262.          break;
  263.       default:
  264.          _mesa_problem(ctx, "Bad depth func in depth_test_span16");
  265.    }
  266.  
  267.    return passed;
  268. }
  269.  
  270.  
  271. static GLuint
  272. depth_test_span32( struct gl_context *ctx, GLuint n,
  273.                    GLuint zbuffer[], const GLuint z[], GLubyte mask[] )
  274. {
  275.    GLuint passed = 0;
  276.  
  277.    /* switch cases ordered from most frequent to less frequent */
  278.    switch (ctx->Depth.Func) {
  279.       case GL_LESS:
  280.          if (ctx->Depth.Mask) {
  281.             /* Update Z buffer */
  282.             GLuint i;
  283.             for (i=0; i<n; i++) {
  284.                if (mask[i]) {
  285.                   if (z[i] < zbuffer[i]) {
  286.                      /* pass */
  287.                      zbuffer[i] = z[i];
  288.                      passed++;
  289.                   }
  290.                   else {
  291.                      /* fail */
  292.                      mask[i] = 0;
  293.                   }
  294.                }
  295.             }
  296.          }
  297.          else {
  298.             /* Don't update Z buffer */
  299.             GLuint i;
  300.             for (i=0; i<n; i++) {
  301.                if (mask[i]) {
  302.                   if (z[i] < zbuffer[i]) {
  303.                      /* pass */
  304.                      passed++;
  305.                   }
  306.                   else {
  307.                      mask[i] = 0;
  308.                   }
  309.                }
  310.             }
  311.          }
  312.          break;
  313.       case GL_LEQUAL:
  314.          if (ctx->Depth.Mask) {
  315.             /* Update Z buffer */
  316.             GLuint i;
  317.             for (i=0;i<n;i++) {
  318.                if (mask[i]) {
  319.                   if (z[i] <= zbuffer[i]) {
  320.                      zbuffer[i] = z[i];
  321.                      passed++;
  322.                   }
  323.                   else {
  324.                      mask[i] = 0;
  325.                   }
  326.                }
  327.             }
  328.          }
  329.          else {
  330.             /* Don't update Z buffer */
  331.             GLuint i;
  332.             for (i=0;i<n;i++) {
  333.                if (mask[i]) {
  334.                   if (z[i] <= zbuffer[i]) {
  335.                      /* pass */
  336.                      passed++;
  337.                   }
  338.                   else {
  339.                      mask[i] = 0;
  340.                   }
  341.                }
  342.             }
  343.          }
  344.          break;
  345.       case GL_GEQUAL:
  346.          if (ctx->Depth.Mask) {
  347.             /* Update Z buffer */
  348.             GLuint i;
  349.             for (i=0;i<n;i++) {
  350.                if (mask[i]) {
  351.                   if (z[i] >= zbuffer[i]) {
  352.                      zbuffer[i] = z[i];
  353.                      passed++;
  354.                   }
  355.                   else {
  356.                      mask[i] = 0;
  357.                   }
  358.                }
  359.             }
  360.          }
  361.          else {
  362.             /* Don't update Z buffer */
  363.             GLuint i;
  364.             for (i=0;i<n;i++) {
  365.                if (mask[i]) {
  366.                   if (z[i] >= zbuffer[i]) {
  367.                      /* pass */
  368.                      passed++;
  369.                   }
  370.                   else {
  371.                      mask[i] = 0;
  372.                   }
  373.                }
  374.             }
  375.          }
  376.          break;
  377.       case GL_GREATER:
  378.          if (ctx->Depth.Mask) {
  379.             /* Update Z buffer */
  380.             GLuint i;
  381.             for (i=0;i<n;i++) {
  382.                if (mask[i]) {
  383.                   if (z[i] > zbuffer[i]) {
  384.                      zbuffer[i] = z[i];
  385.                      passed++;
  386.                   }
  387.                   else {
  388.                      mask[i] = 0;
  389.                   }
  390.                }
  391.             }
  392.          }
  393.          else {
  394.             /* Don't update Z buffer */
  395.             GLuint i;
  396.             for (i=0;i<n;i++) {
  397.                if (mask[i]) {
  398.                   if (z[i] > zbuffer[i]) {
  399.                      /* pass */
  400.                      passed++;
  401.                   }
  402.                   else {
  403.                      mask[i] = 0;
  404.                   }
  405.                }
  406.             }
  407.          }
  408.          break;
  409.       case GL_NOTEQUAL:
  410.          if (ctx->Depth.Mask) {
  411.             /* Update Z buffer */
  412.             GLuint i;
  413.             for (i=0;i<n;i++) {
  414.                if (mask[i]) {
  415.                   if (z[i] != zbuffer[i]) {
  416.                      zbuffer[i] = z[i];
  417.                      passed++;
  418.                   }
  419.                   else {
  420.                      mask[i] = 0;
  421.                   }
  422.                }
  423.             }
  424.          }
  425.          else {
  426.             /* Don't update Z buffer */
  427.             GLuint i;
  428.             for (i=0;i<n;i++) {
  429.                if (mask[i]) {
  430.                   if (z[i] != zbuffer[i]) {
  431.                      /* pass */
  432.                      passed++;
  433.                   }
  434.                   else {
  435.                      mask[i] = 0;
  436.                   }
  437.                }
  438.             }
  439.          }
  440.          break;
  441.       case GL_EQUAL:
  442.          if (ctx->Depth.Mask) {
  443.             /* Update Z buffer */
  444.             GLuint i;
  445.             for (i=0;i<n;i++) {
  446.                if (mask[i]) {
  447.                   if (z[i] == zbuffer[i]) {
  448.                      zbuffer[i] = z[i];
  449.                      passed++;
  450.                   }
  451.                   else {
  452.                      mask[i] = 0;
  453.                   }
  454.                }
  455.             }
  456.          }
  457.          else {
  458.             /* Don't update Z buffer */
  459.             GLuint i;
  460.             for (i=0;i<n;i++) {
  461.                if (mask[i]) {
  462.                   if (z[i] == zbuffer[i]) {
  463.                      /* pass */
  464.                      passed++;
  465.                   }
  466.                   else {
  467.                      mask[i] = 0;
  468.                   }
  469.                }
  470.             }
  471.          }
  472.          break;
  473.       case GL_ALWAYS:
  474.          if (ctx->Depth.Mask) {
  475.             /* Update Z buffer */
  476.             GLuint i;
  477.             for (i=0;i<n;i++) {
  478.                if (mask[i]) {
  479.                   zbuffer[i] = z[i];
  480.                   passed++;
  481.                }
  482.             }
  483.          }
  484.          else {
  485.             /* Don't update Z buffer or mask */
  486.             passed = n;
  487.          }
  488.          break;
  489.       case GL_NEVER:
  490.          memset(mask, 0, n * sizeof(GLubyte));
  491.          break;
  492.       default:
  493.          _mesa_problem(ctx, "Bad depth func in depth_test_span32");
  494.    }
  495.  
  496.    return passed;
  497. }
  498.  
  499.  
  500.  
  501. /**
  502.  * Clamp fragment Z values to the depth near/far range (glDepthRange()).
  503.  * This is used when GL_ARB_depth_clamp/GL_DEPTH_CLAMP is turned on.
  504.  * In that case, vertexes are not clipped against the near/far planes
  505.  * so rasterization will produce fragment Z values outside the usual
  506.  * [0,1] range.
  507.  */
  508. void
  509. _swrast_depth_clamp_span( struct gl_context *ctx, SWspan *span )
  510. {
  511.    struct gl_framebuffer *fb = ctx->DrawBuffer;
  512.    const GLuint count = span->end;
  513.    GLint *zValues = (GLint *) span->array->z; /* sign change */
  514.    GLint min, max;
  515.    GLfloat min_f, max_f;
  516.    GLuint i;
  517.  
  518.    if (ctx->Viewport.Near < ctx->Viewport.Far) {
  519.       min_f = ctx->Viewport.Near;
  520.       max_f = ctx->Viewport.Far;
  521.    } else {
  522.       min_f = ctx->Viewport.Far;
  523.       max_f = ctx->Viewport.Near;
  524.    }
  525.  
  526.    /* Convert floating point values in [0,1] to device Z coordinates in
  527.     * [0, DepthMax].
  528.     * ex: If the Z buffer has 24 bits, DepthMax = 0xffffff.
  529.     *
  530.     * XXX this all falls apart if we have 31 or more bits of Z because
  531.     * the triangle rasterization code produces unsigned Z values.  Negative
  532.     * vertex Z values come out as large fragment Z uints.
  533.     */
  534.    min = (GLint) (min_f * fb->_DepthMaxF);
  535.    max = (GLint) (max_f * fb->_DepthMaxF);
  536.    if (max < 0)
  537.       max = 0x7fffffff; /* catch over flow for 30-bit z */
  538.  
  539.    /* Note that we do the comparisons here using signed integers.
  540.     */
  541.    for (i = 0; i < count; i++) {
  542.       if (zValues[i] < min)
  543.          zValues[i] = min;
  544.       if (zValues[i] > max)
  545.          zValues[i] = max;
  546.    }
  547. }
  548.  
  549.  
  550.  
  551. /*
  552.  * Apply depth test to span of fragments.
  553.  */
  554. static GLuint
  555. depth_test_span( struct gl_context *ctx, SWspan *span)
  556. {
  557.    struct gl_framebuffer *fb = ctx->DrawBuffer;
  558.    struct gl_renderbuffer *rb = fb->_DepthBuffer;
  559.    const GLint x = span->x;
  560.    const GLint y = span->y;
  561.    const GLuint count = span->end;
  562.    const GLuint *zValues = span->array->z;
  563.    GLubyte *mask = span->array->mask;
  564.    GLuint passed;
  565.  
  566.    ASSERT((span->arrayMask & SPAN_XY) == 0);
  567.    ASSERT(span->arrayMask & SPAN_Z);
  568.    
  569.    if (rb->GetPointer(ctx, rb, 0, 0)) {
  570.       /* Directly access buffer */
  571.       if (rb->DataType == GL_UNSIGNED_SHORT) {
  572.          GLushort *zbuffer = (GLushort *) rb->GetPointer(ctx, rb, x, y);
  573.          passed = depth_test_span16(ctx, count, zbuffer, zValues, mask);
  574.       }
  575.       else {
  576.          GLuint *zbuffer = (GLuint *) rb->GetPointer(ctx, rb, x, y);
  577.          ASSERT(rb->DataType == GL_UNSIGNED_INT);
  578.          passed = depth_test_span32(ctx, count, zbuffer, zValues, mask);
  579.       }
  580.    }
  581.    else {
  582.       /* read depth values from buffer, test, write back */
  583.       if (rb->DataType == GL_UNSIGNED_SHORT) {
  584.          GLushort zbuffer[MAX_WIDTH];
  585.          rb->GetRow(ctx, rb, count, x, y, zbuffer);
  586.          passed = depth_test_span16(ctx, count, zbuffer, zValues, mask);
  587.          rb->PutRow(ctx, rb, count, x, y, zbuffer, mask);
  588.       }
  589.       else {
  590.          GLuint zbuffer[MAX_WIDTH];
  591.          ASSERT(rb->DataType == GL_UNSIGNED_INT);
  592.          rb->GetRow(ctx, rb, count, x, y, zbuffer);
  593.          passed = depth_test_span32(ctx, count, zbuffer, zValues, mask);
  594.          rb->PutRow(ctx, rb, count, x, y, zbuffer, mask);
  595.       }
  596.    }
  597.  
  598.    if (passed < count) {
  599.       span->writeAll = GL_FALSE;
  600.    }
  601.    return passed;
  602. }
  603.  
  604.  
  605.  
  606. #define Z_ADDRESS(X, Y)   (zStart + (Y) * stride + (X))
  607.  
  608.  
  609. /*
  610.  * Do depth testing for an array of fragments at assorted locations.
  611.  */
  612. static void
  613. direct_depth_test_pixels16(struct gl_context *ctx, GLushort *zStart, GLuint stride,
  614.                            GLuint n, const GLint x[], const GLint y[],
  615.                            const GLuint z[], GLubyte mask[] )
  616. {
  617.    /* switch cases ordered from most frequent to less frequent */
  618.    switch (ctx->Depth.Func) {
  619.       case GL_LESS:
  620.          if (ctx->Depth.Mask) {
  621.             /* Update Z buffer */
  622.             GLuint i;
  623.             for (i=0; i<n; i++) {
  624.                if (mask[i]) {
  625.                   GLushort *zptr = Z_ADDRESS(x[i], y[i]);
  626.                   if (z[i] < *zptr) {
  627.                      /* pass */
  628.                      *zptr = z[i];
  629.                   }
  630.                   else {
  631.                      /* fail */
  632.                      mask[i] = 0;
  633.                   }
  634.                }
  635.             }
  636.          }
  637.          else {
  638.             /* Don't update Z buffer */
  639.             GLuint i;
  640.             for (i=0; i<n; i++) {
  641.                if (mask[i]) {
  642.                   GLushort *zptr = Z_ADDRESS(x[i], y[i]);
  643.                   if (z[i] < *zptr) {
  644.                      /* pass */
  645.                   }
  646.                   else {
  647.                      /* fail */
  648.                      mask[i] = 0;
  649.                   }
  650.                }
  651.             }
  652.          }
  653.          break;
  654.       case GL_LEQUAL:
  655.          if (ctx->Depth.Mask) {
  656.             /* Update Z buffer */
  657.             GLuint i;
  658.             for (i=0; i<n; i++) {
  659.                if (mask[i]) {
  660.                   GLushort *zptr = Z_ADDRESS(x[i], y[i]);
  661.                   if (z[i] <= *zptr) {
  662.                      /* pass */
  663.                      *zptr = z[i];
  664.                   }
  665.                   else {
  666.                      /* fail */
  667.                      mask[i] = 0;
  668.                   }
  669.                }
  670.             }
  671.          }
  672.          else {
  673.             /* Don't update Z buffer */
  674.             GLuint i;
  675.             for (i=0; i<n; i++) {
  676.                if (mask[i]) {
  677.                   GLushort *zptr = Z_ADDRESS(x[i], y[i]);
  678.                   if (z[i] <= *zptr) {
  679.                      /* pass */
  680.                   }
  681.                   else {
  682.                      /* fail */
  683.                      mask[i] = 0;
  684.                   }
  685.                }
  686.             }
  687.          }
  688.          break;
  689.       case GL_GEQUAL:
  690.          if (ctx->Depth.Mask) {
  691.             /* Update Z buffer */
  692.             GLuint i;
  693.             for (i=0; i<n; i++) {
  694.                if (mask[i]) {
  695.                   GLushort *zptr = Z_ADDRESS(x[i], y[i]);
  696.                   if (z[i] >= *zptr) {
  697.                      /* pass */
  698.                      *zptr = z[i];
  699.                   }
  700.                   else {
  701.                      /* fail */
  702.                      mask[i] = 0;
  703.                   }
  704.                }
  705.             }
  706.          }
  707.          else {
  708.             /* Don't update Z buffer */
  709.             GLuint i;
  710.             for (i=0; i<n; i++) {
  711.                if (mask[i]) {
  712.                   GLushort *zptr = Z_ADDRESS(x[i], y[i]);
  713.                   if (z[i] >= *zptr) {
  714.                      /* pass */
  715.                   }
  716.                   else {
  717.                      /* fail */
  718.                      mask[i] = 0;
  719.                   }
  720.                }
  721.             }
  722.          }
  723.          break;
  724.       case GL_GREATER:
  725.          if (ctx->Depth.Mask) {
  726.             /* Update Z buffer */
  727.             GLuint i;
  728.             for (i=0; i<n; i++) {
  729.                if (mask[i]) {
  730.                   GLushort *zptr = Z_ADDRESS(x[i], y[i]);
  731.                   if (z[i] > *zptr) {
  732.                      /* pass */
  733.                      *zptr = z[i];
  734.                   }
  735.                   else {
  736.                      /* fail */
  737.                      mask[i] = 0;
  738.                   }
  739.                }
  740.             }
  741.          }
  742.          else {
  743.             /* Don't update Z buffer */
  744.             GLuint i;
  745.             for (i=0; i<n; i++) {
  746.                if (mask[i]) {
  747.                   GLushort *zptr = Z_ADDRESS(x[i], y[i]);
  748.                   if (z[i] > *zptr) {
  749.                      /* pass */
  750.                   }
  751.                   else {
  752.                      /* fail */
  753.                      mask[i] = 0;
  754.                   }
  755.                }
  756.             }
  757.          }
  758.          break;
  759.       case GL_NOTEQUAL:
  760.          if (ctx->Depth.Mask) {
  761.             /* Update Z buffer */
  762.             GLuint i;
  763.             for (i=0; i<n; i++) {
  764.                if (mask[i]) {
  765.                   GLushort *zptr = Z_ADDRESS(x[i], y[i]);
  766.                   if (z[i] != *zptr) {
  767.                      /* pass */
  768.                      *zptr = z[i];
  769.                   }
  770.                   else {
  771.                      /* fail */
  772.                      mask[i] = 0;
  773.                   }
  774.                }
  775.             }
  776.          }
  777.          else {
  778.             /* Don't update Z buffer */
  779.             GLuint i;
  780.             for (i=0; i<n; i++) {
  781.                if (mask[i]) {
  782.                   GLushort *zptr = Z_ADDRESS(x[i], y[i]);
  783.                   if (z[i] != *zptr) {
  784.                      /* pass */
  785.                   }
  786.                   else {
  787.                      /* fail */
  788.                      mask[i] = 0;
  789.                   }
  790.                }
  791.             }
  792.          }
  793.          break;
  794.       case GL_EQUAL:
  795.          if (ctx->Depth.Mask) {
  796.             /* Update Z buffer */
  797.             GLuint i;
  798.             for (i=0; i<n; i++) {
  799.                if (mask[i]) {
  800.                   GLushort *zptr = Z_ADDRESS(x[i], y[i]);
  801.                   if (z[i] == *zptr) {
  802.                      /* pass */
  803.                      *zptr = z[i];
  804.                   }
  805.                   else {
  806.                      /* fail */
  807.                      mask[i] = 0;
  808.                   }
  809.                }
  810.             }
  811.          }
  812.          else {
  813.             /* Don't update Z buffer */
  814.             GLuint i;
  815.             for (i=0; i<n; i++) {
  816.                if (mask[i]) {
  817.                   GLushort *zptr = Z_ADDRESS(x[i], y[i]);
  818.                   if (z[i] == *zptr) {
  819.                      /* pass */
  820.                   }
  821.                   else {
  822.                      /* fail */
  823.                      mask[i] = 0;
  824.                   }
  825.                }
  826.             }
  827.          }
  828.          break;
  829.       case GL_ALWAYS:
  830.          if (ctx->Depth.Mask) {
  831.             /* Update Z buffer */
  832.             GLuint i;
  833.             for (i=0; i<n; i++) {
  834.                if (mask[i]) {
  835.                   GLushort *zptr = Z_ADDRESS(x[i], y[i]);
  836.                   *zptr = z[i];
  837.                }
  838.             }
  839.          }
  840.          else {
  841.             /* Don't update Z buffer or mask */
  842.          }
  843.          break;
  844.       case GL_NEVER:
  845.          /* depth test never passes */
  846.          memset(mask, 0, n * sizeof(GLubyte));
  847.          break;
  848.       default:
  849.          _mesa_problem(ctx, "Bad depth func in direct_depth_test_pixels");
  850.    }
  851. }
  852.  
  853.  
  854.  
  855. /*
  856.  * Do depth testing for an array of fragments with direct access to zbuffer.
  857.  */
  858. static void
  859. direct_depth_test_pixels32(struct gl_context *ctx, GLuint *zStart, GLuint stride,
  860.                            GLuint n, const GLint x[], const GLint y[],
  861.                            const GLuint z[], GLubyte mask[] )
  862. {
  863.    /* switch cases ordered from most frequent to less frequent */
  864.    switch (ctx->Depth.Func) {
  865.       case GL_LESS:
  866.          if (ctx->Depth.Mask) {
  867.             /* Update Z buffer */
  868.             GLuint i;
  869.             for (i=0; i<n; i++) {
  870.                if (mask[i]) {
  871.                   GLuint *zptr = Z_ADDRESS(x[i], y[i]);
  872.                   if (z[i] < *zptr) {
  873.                      /* pass */
  874.                      *zptr = z[i];
  875.                   }
  876.                   else {
  877.                      /* fail */
  878.                      mask[i] = 0;
  879.                   }
  880.                }
  881.             }
  882.          }
  883.          else {
  884.             /* Don't update Z buffer */
  885.             GLuint i;
  886.             for (i=0; i<n; i++) {
  887.                if (mask[i]) {
  888.                   GLuint *zptr = Z_ADDRESS(x[i], y[i]);
  889.                   if (z[i] < *zptr) {
  890.                      /* pass */
  891.                   }
  892.                   else {
  893.                      /* fail */
  894.                      mask[i] = 0;
  895.                   }
  896.                }
  897.             }
  898.          }
  899.          break;
  900.       case GL_LEQUAL:
  901.          if (ctx->Depth.Mask) {
  902.             /* Update Z buffer */
  903.             GLuint i;
  904.             for (i=0; i<n; i++) {
  905.                if (mask[i]) {
  906.                   GLuint *zptr = Z_ADDRESS(x[i], y[i]);
  907.                   if (z[i] <= *zptr) {
  908.                      /* pass */
  909.                      *zptr = z[i];
  910.                   }
  911.                   else {
  912.                      /* fail */
  913.                      mask[i] = 0;
  914.                   }
  915.                }
  916.             }
  917.          }
  918.          else {
  919.             /* Don't update Z buffer */
  920.             GLuint i;
  921.             for (i=0; i<n; i++) {
  922.                if (mask[i]) {
  923.                   GLuint *zptr = Z_ADDRESS(x[i], y[i]);
  924.                   if (z[i] <= *zptr) {
  925.                      /* pass */
  926.                   }
  927.                   else {
  928.                      /* fail */
  929.                      mask[i] = 0;
  930.                   }
  931.                }
  932.             }
  933.          }
  934.          break;
  935.       case GL_GEQUAL:
  936.          if (ctx->Depth.Mask) {
  937.             /* Update Z buffer */
  938.             GLuint i;
  939.             for (i=0; i<n; i++) {
  940.                if (mask[i]) {
  941.                   GLuint *zptr = Z_ADDRESS(x[i], y[i]);
  942.                   if (z[i] >= *zptr) {
  943.                      /* pass */
  944.                      *zptr = z[i];
  945.                   }
  946.                   else {
  947.                      /* fail */
  948.                      mask[i] = 0;
  949.                   }
  950.                }
  951.             }
  952.          }
  953.          else {
  954.             /* Don't update Z buffer */
  955.             GLuint i;
  956.             for (i=0; i<n; i++) {
  957.                if (mask[i]) {
  958.                   GLuint *zptr = Z_ADDRESS(x[i], y[i]);
  959.                   if (z[i] >= *zptr) {
  960.                      /* pass */
  961.                   }
  962.                   else {
  963.                      /* fail */
  964.                      mask[i] = 0;
  965.                   }
  966.                }
  967.             }
  968.          }
  969.          break;
  970.       case GL_GREATER:
  971.          if (ctx->Depth.Mask) {
  972.             /* Update Z buffer */
  973.             GLuint i;
  974.             for (i=0; i<n; i++) {
  975.                if (mask[i]) {
  976.                   GLuint *zptr = Z_ADDRESS(x[i], y[i]);
  977.                   if (z[i] > *zptr) {
  978.                      /* pass */
  979.                      *zptr = z[i];
  980.                   }
  981.                   else {
  982.                      /* fail */
  983.                      mask[i] = 0;
  984.                   }
  985.                }
  986.             }
  987.          }
  988.          else {
  989.             /* Don't update Z buffer */
  990.             GLuint i;
  991.             for (i=0; i<n; i++) {
  992.                if (mask[i]) {
  993.                   GLuint *zptr = Z_ADDRESS(x[i], y[i]);
  994.                   if (z[i] > *zptr) {
  995.                      /* pass */
  996.                   }
  997.                   else {
  998.                      /* fail */
  999.                      mask[i] = 0;
  1000.                   }
  1001.                }
  1002.             }
  1003.          }
  1004.          break;
  1005.       case GL_NOTEQUAL:
  1006.          if (ctx->Depth.Mask) {
  1007.             /* Update Z buffer */
  1008.             GLuint i;
  1009.             for (i=0; i<n; i++) {
  1010.                if (mask[i]) {
  1011.                   GLuint *zptr = Z_ADDRESS(x[i], y[i]);
  1012.                   if (z[i] != *zptr) {
  1013.                      /* pass */
  1014.                      *zptr = z[i];
  1015.                   }
  1016.                   else {
  1017.                      /* fail */
  1018.                      mask[i] = 0;
  1019.                   }
  1020.                }
  1021.             }
  1022.          }
  1023.          else {
  1024.             /* Don't update Z buffer */
  1025.             GLuint i;
  1026.             for (i=0; i<n; i++) {
  1027.                if (mask[i]) {
  1028.                   GLuint *zptr = Z_ADDRESS(x[i], y[i]);
  1029.                   if (z[i] != *zptr) {
  1030.                      /* pass */
  1031.                   }
  1032.                   else {
  1033.                      /* fail */
  1034.                      mask[i] = 0;
  1035.                   }
  1036.                }
  1037.             }
  1038.          }
  1039.          break;
  1040.       case GL_EQUAL:
  1041.          if (ctx->Depth.Mask) {
  1042.             /* Update Z buffer */
  1043.             GLuint i;
  1044.             for (i=0; i<n; i++) {
  1045.                if (mask[i]) {
  1046.                   GLuint *zptr = Z_ADDRESS(x[i], y[i]);
  1047.                   if (z[i] == *zptr) {
  1048.                      /* pass */
  1049.                      *zptr = z[i];
  1050.                   }
  1051.                   else {
  1052.                      /* fail */
  1053.                      mask[i] = 0;
  1054.                   }
  1055.                }
  1056.             }
  1057.          }
  1058.          else {
  1059.             /* Don't update Z buffer */
  1060.             GLuint i;
  1061.             for (i=0; i<n; i++) {
  1062.                if (mask[i]) {
  1063.                   GLuint *zptr = Z_ADDRESS(x[i], y[i]);
  1064.                   if (z[i] == *zptr) {
  1065.                      /* pass */
  1066.                   }
  1067.                   else {
  1068.                      /* fail */
  1069.                      mask[i] = 0;
  1070.                   }
  1071.                }
  1072.             }
  1073.          }
  1074.          break;
  1075.       case GL_ALWAYS:
  1076.          if (ctx->Depth.Mask) {
  1077.             /* Update Z buffer */
  1078.             GLuint i;
  1079.             for (i=0; i<n; i++) {
  1080.                if (mask[i]) {
  1081.                   GLuint *zptr = Z_ADDRESS(x[i], y[i]);
  1082.                   *zptr = z[i];
  1083.                }
  1084.             }
  1085.          }
  1086.          else {
  1087.             /* Don't update Z buffer or mask */
  1088.          }
  1089.          break;
  1090.       case GL_NEVER:
  1091.          /* depth test never passes */
  1092.          memset(mask, 0, n * sizeof(GLubyte));
  1093.          break;
  1094.       default:
  1095.          _mesa_problem(ctx, "Bad depth func in direct_depth_test_pixels");
  1096.    }
  1097. }
  1098.  
  1099.  
  1100.  
  1101.  
  1102. static GLuint
  1103. depth_test_pixels( struct gl_context *ctx, SWspan *span )
  1104. {
  1105.    struct gl_framebuffer *fb = ctx->DrawBuffer;
  1106.    struct gl_renderbuffer *rb = fb->_DepthBuffer;
  1107.    const GLuint count = span->end;
  1108.    const GLint *x = span->array->x;
  1109.    const GLint *y = span->array->y;
  1110.    const GLuint *z = span->array->z;
  1111.    GLubyte *mask = span->array->mask;
  1112.  
  1113.    if (rb->GetPointer(ctx, rb, 0, 0)) {
  1114.       /* Directly access values */
  1115.       if (rb->DataType == GL_UNSIGNED_SHORT) {
  1116.          GLushort *zStart = (GLushort *) rb->Data;
  1117.          GLuint stride = rb->Width;
  1118.          direct_depth_test_pixels16(ctx, zStart, stride, count, x, y, z, mask);
  1119.       }
  1120.       else {
  1121.          GLuint *zStart = (GLuint *) rb->Data;
  1122.          GLuint stride = rb->Width;
  1123.          ASSERT(rb->DataType == GL_UNSIGNED_INT);
  1124.          direct_depth_test_pixels32(ctx, zStart, stride, count, x, y, z, mask);
  1125.       }
  1126.    }
  1127.    else {
  1128.       /* read depth values from buffer, test, write back */
  1129.       if (rb->DataType == GL_UNSIGNED_SHORT) {
  1130.          GLushort zbuffer[MAX_WIDTH];
  1131.          _swrast_get_values(ctx, rb, count, x, y, zbuffer, sizeof(GLushort));
  1132.          depth_test_span16(ctx, count, zbuffer, z, mask);
  1133.          rb->PutValues(ctx, rb, count, x, y, zbuffer, mask);
  1134.       }
  1135.       else {
  1136.          GLuint zbuffer[MAX_WIDTH];
  1137.          ASSERT(rb->DataType == GL_UNSIGNED_INT);
  1138.          _swrast_get_values(ctx, rb, count, x, y, zbuffer, sizeof(GLuint));
  1139.          depth_test_span32(ctx, count, zbuffer, z, mask);
  1140.          rb->PutValues(ctx, rb, count, x, y, zbuffer, mask);
  1141.       }
  1142.    }
  1143.  
  1144.    return count; /* not really correct, but OK */
  1145. }
  1146.  
  1147.  
  1148. /**
  1149.  * Apply depth (Z) buffer testing to the span.
  1150.  * \return approx number of pixels that passed (only zero is reliable)
  1151.  */
  1152. GLuint
  1153. _swrast_depth_test_span( struct gl_context *ctx, SWspan *span)
  1154. {
  1155.    if (span->arrayMask & SPAN_XY)
  1156.       return depth_test_pixels(ctx, span);
  1157.    else
  1158.       return depth_test_span(ctx, span);
  1159. }
  1160.  
  1161.  
  1162. /**
  1163.  * GL_EXT_depth_bounds_test extension.
  1164.  * Discard fragments depending on whether the corresponding Z-buffer
  1165.  * values are outside the depth bounds test range.
  1166.  * Note: we test the Z buffer values, not the fragment Z values!
  1167.  * \return GL_TRUE if any fragments pass, GL_FALSE if no fragments pass
  1168.  */
  1169. GLboolean
  1170. _swrast_depth_bounds_test( struct gl_context *ctx, SWspan *span )
  1171. {
  1172.    struct gl_framebuffer *fb = ctx->DrawBuffer;
  1173.    struct gl_renderbuffer *rb = fb->_DepthBuffer;
  1174.    GLuint zMin = (GLuint) (ctx->Depth.BoundsMin * fb->_DepthMaxF + 0.5F);
  1175.    GLuint zMax = (GLuint) (ctx->Depth.BoundsMax * fb->_DepthMaxF + 0.5F);
  1176.    GLubyte *mask = span->array->mask;
  1177.    const GLuint count = span->end;
  1178.    GLuint i;
  1179.    GLboolean anyPass = GL_FALSE;
  1180.  
  1181.    if (rb->DataType == GL_UNSIGNED_SHORT) {
  1182.       /* get 16-bit values */
  1183.       GLushort zbuffer16[MAX_WIDTH], *zbuffer;
  1184.       if (span->arrayMask & SPAN_XY) {
  1185.          _swrast_get_values(ctx, rb, count, span->array->x, span->array->y,
  1186.                             zbuffer16, sizeof(GLushort));
  1187.          zbuffer = zbuffer16;
  1188.       }
  1189.       else {
  1190.          zbuffer = (GLushort*) rb->GetPointer(ctx, rb, span->x, span->y);
  1191.          if (!zbuffer) {
  1192.             rb->GetRow(ctx, rb, count, span->x, span->y, zbuffer16);
  1193.             zbuffer = zbuffer16;
  1194.          }
  1195.       }
  1196.       assert(zbuffer);
  1197.  
  1198.       /* Now do the tests */
  1199.       for (i = 0; i < count; i++) {
  1200.          if (mask[i]) {
  1201.             if (zbuffer[i] < zMin || zbuffer[i] > zMax)
  1202.                mask[i] = GL_FALSE;
  1203.             else
  1204.                anyPass = GL_TRUE;
  1205.          }
  1206.       }
  1207.    }
  1208.    else {
  1209.       /* get 32-bit values */
  1210.       GLuint zbuffer32[MAX_WIDTH], *zbuffer;
  1211.       ASSERT(rb->DataType == GL_UNSIGNED_INT);
  1212.       if (span->arrayMask & SPAN_XY) {
  1213.          _swrast_get_values(ctx, rb, count, span->array->x, span->array->y,
  1214.                             zbuffer32, sizeof(GLuint));
  1215.          zbuffer = zbuffer32;
  1216.       }
  1217.       else {
  1218.          zbuffer = (GLuint*) rb->GetPointer(ctx, rb, span->x, span->y);
  1219.          if (!zbuffer) {
  1220.             rb->GetRow(ctx, rb, count, span->x, span->y, zbuffer32);
  1221.             zbuffer = zbuffer32;
  1222.          }
  1223.       }
  1224.       assert(zbuffer);
  1225.  
  1226.       /* Now do the tests */
  1227.       for (i = 0; i < count; i++) {
  1228.          if (mask[i]) {
  1229.             if (zbuffer[i] < zMin || zbuffer[i] > zMax)
  1230.                mask[i] = GL_FALSE;
  1231.             else
  1232.                anyPass = GL_TRUE;
  1233.          }
  1234.       }
  1235.    }
  1236.  
  1237.    return anyPass;
  1238. }
  1239.  
  1240.  
  1241.  
  1242. /**********************************************************************/
  1243. /*****                      Read Depth Buffer                     *****/
  1244. /**********************************************************************/
  1245.  
  1246.  
  1247. /**
  1248.  * Read a span of depth values from the given depth renderbuffer, returning
  1249.  * the values as GLfloats.
  1250.  * This function does clipping to prevent reading outside the depth buffer's
  1251.  * bounds.  Though the clipping is redundant when we're called from
  1252.  * _swrast_ReadPixels.
  1253.  */
  1254. void
  1255. _swrast_read_depth_span_float( struct gl_context *ctx, struct gl_renderbuffer *rb,
  1256.                                GLint n, GLint x, GLint y, GLfloat depth[] )
  1257. {
  1258.    const GLfloat scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
  1259.  
  1260.    if (!rb) {
  1261.       /* really only doing this to prevent FP exceptions later */
  1262.       memset(depth, 0, n * sizeof(GLfloat));
  1263.       return;
  1264.    }
  1265.  
  1266.    ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT);
  1267.  
  1268.    if (y < 0 || y >= (GLint) rb->Height ||
  1269.        x + n <= 0 || x >= (GLint) rb->Width) {
  1270.       /* span is completely outside framebuffer */
  1271.       memset(depth, 0, n * sizeof(GLfloat));
  1272.       return;
  1273.    }
  1274.  
  1275.    if (x < 0) {
  1276.       GLint dx = -x;
  1277.       GLint i;
  1278.       for (i = 0; i < dx; i++)
  1279.          depth[i] = 0.0;
  1280.       x = 0;
  1281.       n -= dx;
  1282.       depth += dx;
  1283.    }
  1284.    if (x + n > (GLint) rb->Width) {
  1285.       GLint dx = x + n - (GLint) rb->Width;
  1286.       GLint i;
  1287.       for (i = 0; i < dx; i++)
  1288.          depth[n - i - 1] = 0.0;
  1289.       n -= dx;
  1290.    }
  1291.    if (n <= 0) {
  1292.       return;
  1293.    }
  1294.  
  1295.    if (rb->DataType == GL_UNSIGNED_INT) {
  1296.       GLuint temp[MAX_WIDTH];
  1297.       GLint i;
  1298.       rb->GetRow(ctx, rb, n, x, y, temp);
  1299.       for (i = 0; i < n; i++) {
  1300.          depth[i] = temp[i] * scale;
  1301.       }
  1302.    }
  1303.    else if (rb->DataType == GL_UNSIGNED_SHORT) {
  1304.       GLushort temp[MAX_WIDTH];
  1305.       GLint i;
  1306.       rb->GetRow(ctx, rb, n, x, y, temp);
  1307.       for (i = 0; i < n; i++) {
  1308.          depth[i] = temp[i] * scale;
  1309.       }
  1310.    }
  1311.    else {
  1312.       _mesa_problem(ctx, "Invalid depth renderbuffer data type");
  1313.    }
  1314. }
  1315.  
  1316.  
  1317. /**
  1318.  * As above, but return 32-bit GLuint values.
  1319.  */
  1320. void
  1321. _swrast_read_depth_span_uint( struct gl_context *ctx, struct gl_renderbuffer *rb,
  1322.                               GLint n, GLint x, GLint y, GLuint depth[] )
  1323. {
  1324.    GLuint depthBits;
  1325.  
  1326.    if (!rb) {
  1327.       /* really only doing this to prevent FP exceptions later */
  1328.       memset(depth, 0, n * sizeof(GLuint));
  1329.       return;
  1330.    }
  1331.  
  1332.    depthBits = _mesa_get_format_bits(rb->Format, GL_DEPTH_BITS);
  1333.  
  1334.    ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT);
  1335.  
  1336.    if (y < 0 || y >= (GLint) rb->Height ||
  1337.        x + n <= 0 || x >= (GLint) rb->Width) {
  1338.       /* span is completely outside framebuffer */
  1339.       memset(depth, 0, n * sizeof(GLfloat));
  1340.       return;
  1341.    }
  1342.  
  1343.    if (x < 0) {
  1344.       GLint dx = -x;
  1345.       GLint i;
  1346.       for (i = 0; i < dx; i++)
  1347.          depth[i] = 0;
  1348.       x = 0;
  1349.       n -= dx;
  1350.       depth += dx;
  1351.    }
  1352.    if (x + n > (GLint) rb->Width) {
  1353.       GLint dx = x + n - (GLint) rb->Width;
  1354.       GLint i;
  1355.       for (i = 0; i < dx; i++)
  1356.          depth[n - i - 1] = 0;
  1357.       n -= dx;
  1358.    }
  1359.    if (n <= 0) {
  1360.       return;
  1361.    }
  1362.  
  1363.    if (rb->DataType == GL_UNSIGNED_INT) {
  1364.       rb->GetRow(ctx, rb, n, x, y, depth);
  1365.       if (depthBits < 32) {
  1366.          GLuint shift = 32 - depthBits;
  1367.          GLint i;
  1368.          for (i = 0; i < n; i++) {
  1369.             GLuint z = depth[i];
  1370.             depth[i] = z << shift; /* XXX lsb bits? */
  1371.          }
  1372.       }
  1373.    }
  1374.    else if (rb->DataType == GL_UNSIGNED_SHORT) {
  1375.       GLushort temp[MAX_WIDTH];
  1376.       GLint i;
  1377.       rb->GetRow(ctx, rb, n, x, y, temp);
  1378.       if (depthBits == 16) {
  1379.          for (i = 0; i < n; i++) {
  1380.             GLuint z = temp[i];
  1381.             depth[i] = (z << 16) | z;
  1382.          }
  1383.       }
  1384.       else {
  1385.          GLuint shift = 16 - depthBits;
  1386.          for (i = 0; i < n; i++) {
  1387.             GLuint z = temp[i];
  1388.             depth[i] = (z << (shift + 16)) | (z << shift); /* XXX lsb bits? */
  1389.          }
  1390.       }
  1391.    }
  1392.    else {
  1393.       _mesa_problem(ctx, "Invalid depth renderbuffer data type");
  1394.    }
  1395. }
  1396.  
  1397.  
  1398.  
  1399. /**
  1400.  * Clear the given z/depth renderbuffer.
  1401.  */
  1402. void
  1403. _swrast_clear_depth_buffer( struct gl_context *ctx, struct gl_renderbuffer *rb )
  1404. {
  1405.    GLuint clearValue;
  1406.    GLint x, y, width, height;
  1407.  
  1408.    if (!rb || !ctx->Depth.Mask) {
  1409.       /* no depth buffer, or writing to it is disabled */
  1410.       return;
  1411.    }
  1412.  
  1413.    /* compute integer clearing value */
  1414.    if (ctx->Depth.Clear == 1.0) {
  1415.       clearValue = ctx->DrawBuffer->_DepthMax;
  1416.    }
  1417.    else {
  1418.       clearValue = (GLuint) (ctx->Depth.Clear * ctx->DrawBuffer->_DepthMaxF);
  1419.    }
  1420.  
  1421.    assert(rb->_BaseFormat == GL_DEPTH_COMPONENT);
  1422.  
  1423.    /* compute region to clear */
  1424.    x = ctx->DrawBuffer->_Xmin;
  1425.    y = ctx->DrawBuffer->_Ymin;
  1426.    width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
  1427.    height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
  1428.  
  1429.    if (rb->GetPointer(ctx, rb, 0, 0)) {
  1430.       /* Direct buffer access is possible.  Either this is just malloc'd
  1431.        * memory, or perhaps the driver mmap'd the zbuffer memory.
  1432.        */
  1433.       if (rb->DataType == GL_UNSIGNED_SHORT) {
  1434.          if ((clearValue & 0xff) == ((clearValue >> 8) & 0xff) &&
  1435.              ((GLushort *) rb->GetPointer(ctx, rb, 0, 0) + width ==
  1436.               (GLushort *) rb->GetPointer(ctx, rb, 0, 1))) {
  1437.             /* optimized case */
  1438.             GLushort *dst = (GLushort *) rb->GetPointer(ctx, rb, x, y);
  1439.             GLuint len = width * height * sizeof(GLushort);
  1440.             memset(dst, (clearValue & 0xff), len);
  1441.          }
  1442.          else {
  1443.             /* general case */
  1444.             GLint i, j;
  1445.             for (i = 0; i < height; i++) {
  1446.                GLushort *dst = (GLushort *) rb->GetPointer(ctx, rb, x, y + i);
  1447.                for (j = 0; j < width; j++) {
  1448.                   dst[j] = clearValue;
  1449.                }
  1450.             }
  1451.          }
  1452.       }
  1453.       else {
  1454.          GLint i, j;
  1455.          ASSERT(rb->DataType == GL_UNSIGNED_INT);
  1456.          for (i = 0; i < height; i++) {
  1457.             GLuint *dst = (GLuint *) rb->GetPointer(ctx, rb, x, y + i);
  1458.             for (j = 0; j < width; j++) {
  1459.                dst[j] = clearValue;
  1460.             }
  1461.          }
  1462.       }
  1463.    }
  1464.    else {
  1465.       /* Direct access not possible.  Use PutRow to write new values. */
  1466.       if (rb->DataType == GL_UNSIGNED_SHORT) {
  1467.          GLushort clearVal16 = (GLushort) (clearValue & 0xffff);
  1468.          GLint i;
  1469.          for (i = 0; i < height; i++) {
  1470.             rb->PutMonoRow(ctx, rb, width, x, y + i, &clearVal16, NULL);
  1471.          }
  1472.       }
  1473.       else if (rb->DataType == GL_UNSIGNED_INT) {
  1474.          GLint i;
  1475.          ASSERT(sizeof(clearValue) == sizeof(GLuint));
  1476.          for (i = 0; i < height; i++) {
  1477.             rb->PutMonoRow(ctx, rb, width, x, y + i, &clearValue, NULL);
  1478.          }
  1479.       }
  1480.       else {
  1481.          _mesa_problem(ctx, "bad depth renderbuffer DataType");
  1482.       }
  1483.    }
  1484. }
  1485.