17117f1b4Smrg/*
27117f1b4Smrg * Mesa 3-D graphics library
37117f1b4Smrg *
4c1f859d4Smrg * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
57117f1b4Smrg *
67117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a
77117f1b4Smrg * copy of this software and associated documentation files (the "Software"),
87117f1b4Smrg * to deal in the Software without restriction, including without limitation
97117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
107117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the
117117f1b4Smrg * Software is furnished to do so, subject to the following conditions:
127117f1b4Smrg *
137117f1b4Smrg * The above copyright notice and this permission notice shall be included
147117f1b4Smrg * in all copies or substantial portions of the Software.
157117f1b4Smrg *
167117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
177117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
187117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE.
237117f1b4Smrg */
247117f1b4Smrg
257117f1b4Smrg
26c1f859d4Smrg#include "main/glheader.h"
27c1f859d4Smrg#include "main/context.h"
284a49301eSmrg#include "main/formats.h"
29af69d88dSmrg#include "main/format_unpack.h"
30af69d88dSmrg#include "main/format_pack.h"
31c1f859d4Smrg#include "main/macros.h"
327ec681f3Smrg
337117f1b4Smrg
34af69d88dSmrg#include "s_context.h"
357117f1b4Smrg#include "s_depth.h"
367117f1b4Smrg#include "s_span.h"
377117f1b4Smrg
387117f1b4Smrg
39af69d88dSmrg
40af69d88dSmrg#define Z_TEST(COMPARE)                      \
41af69d88dSmrg   do {                                      \
42af69d88dSmrg      GLuint i;                              \
43af69d88dSmrg      for (i = 0; i < n; i++) {              \
44af69d88dSmrg         if (mask[i]) {                      \
45af69d88dSmrg            if (COMPARE) {                   \
46af69d88dSmrg               /* pass */                    \
47af69d88dSmrg               if (write) {                  \
48af69d88dSmrg                  zbuffer[i] = zfrag[i];     \
49af69d88dSmrg               }                             \
50af69d88dSmrg               passed++;                     \
51af69d88dSmrg            }                                \
52af69d88dSmrg            else {                           \
53af69d88dSmrg               /* fail */                    \
54af69d88dSmrg               mask[i] = 0;                  \
55af69d88dSmrg            }                                \
56af69d88dSmrg         }                                   \
57af69d88dSmrg      }                                      \
58af69d88dSmrg   } while (0)
59af69d88dSmrg
60af69d88dSmrg
617117f1b4Smrg/**
62af69d88dSmrg * Do depth test for an array of 16-bit Z values.
63af69d88dSmrg * @param zbuffer  array of Z buffer values (16-bit)
64af69d88dSmrg * @param zfrag  array of fragment Z values (use 16-bit in 32-bit uint)
65af69d88dSmrg * @param mask  which fragments are alive, killed afterward
66af69d88dSmrg * @return  number of fragments which pass the test.
677117f1b4Smrg */
687117f1b4Smrgstatic GLuint
693464ebd5Sriastradhdepth_test_span16( struct gl_context *ctx, GLuint n,
70af69d88dSmrg                   GLushort zbuffer[], const GLuint zfrag[], GLubyte mask[] )
717117f1b4Smrg{
72af69d88dSmrg   const GLboolean write = ctx->Depth.Mask;
737117f1b4Smrg   GLuint passed = 0;
747117f1b4Smrg
757117f1b4Smrg   /* switch cases ordered from most frequent to less frequent */
767117f1b4Smrg   switch (ctx->Depth.Func) {
77af69d88dSmrg   case GL_LESS:
78af69d88dSmrg      Z_TEST(zfrag[i] < zbuffer[i]);
79af69d88dSmrg      break;
80af69d88dSmrg   case GL_LEQUAL:
81af69d88dSmrg      Z_TEST(zfrag[i] <= zbuffer[i]);
82af69d88dSmrg      break;
83af69d88dSmrg   case GL_GEQUAL:
84af69d88dSmrg      Z_TEST(zfrag[i] >= zbuffer[i]);
85af69d88dSmrg      break;
86af69d88dSmrg   case GL_GREATER:
87af69d88dSmrg      Z_TEST(zfrag[i] > zbuffer[i]);
88af69d88dSmrg      break;
89af69d88dSmrg   case GL_NOTEQUAL:
90af69d88dSmrg      Z_TEST(zfrag[i] != zbuffer[i]);
91af69d88dSmrg      break;
92af69d88dSmrg   case GL_EQUAL:
93af69d88dSmrg      Z_TEST(zfrag[i] == zbuffer[i]);
94af69d88dSmrg      break;
95af69d88dSmrg   case GL_ALWAYS:
96af69d88dSmrg      Z_TEST(1);
97af69d88dSmrg      break;
98af69d88dSmrg   case GL_NEVER:
99af69d88dSmrg      memset(mask, 0, n * sizeof(GLubyte));
100af69d88dSmrg      break;
101af69d88dSmrg   default:
102af69d88dSmrg      _mesa_problem(ctx, "Bad depth func in depth_test_span16");
1037117f1b4Smrg   }
1047117f1b4Smrg
1057117f1b4Smrg   return passed;
1067117f1b4Smrg}
1077117f1b4Smrg
1087117f1b4Smrg
109af69d88dSmrg/**
110af69d88dSmrg * Do depth test for an array of 32-bit Z values.
111af69d88dSmrg * @param zbuffer  array of Z buffer values (32-bit)
112af69d88dSmrg * @param zfrag  array of fragment Z values (use 32-bits in 32-bit uint)
113af69d88dSmrg * @param mask  which fragments are alive, killed afterward
114af69d88dSmrg * @return  number of fragments which pass the test.
115af69d88dSmrg */
1167117f1b4Smrgstatic GLuint
1173464ebd5Sriastradhdepth_test_span32( struct gl_context *ctx, GLuint n,
118af69d88dSmrg                   GLuint zbuffer[], const GLuint zfrag[], GLubyte mask[])
1197117f1b4Smrg{
120af69d88dSmrg   const GLboolean write = ctx->Depth.Mask;
1217117f1b4Smrg   GLuint passed = 0;
1227117f1b4Smrg
1237117f1b4Smrg   /* switch cases ordered from most frequent to less frequent */
1247117f1b4Smrg   switch (ctx->Depth.Func) {
125af69d88dSmrg   case GL_LESS:
126af69d88dSmrg      Z_TEST(zfrag[i] < zbuffer[i]);
127af69d88dSmrg      break;
128af69d88dSmrg   case GL_LEQUAL:
129af69d88dSmrg      Z_TEST(zfrag[i] <= zbuffer[i]);
130af69d88dSmrg      break;
131af69d88dSmrg   case GL_GEQUAL:
132af69d88dSmrg      Z_TEST(zfrag[i] >= zbuffer[i]);
133af69d88dSmrg      break;
134af69d88dSmrg   case GL_GREATER:
135af69d88dSmrg      Z_TEST(zfrag[i] > zbuffer[i]);
136af69d88dSmrg      break;
137af69d88dSmrg   case GL_NOTEQUAL:
138af69d88dSmrg      Z_TEST(zfrag[i] != zbuffer[i]);
139af69d88dSmrg      break;
140af69d88dSmrg   case GL_EQUAL:
141af69d88dSmrg      Z_TEST(zfrag[i] == zbuffer[i]);
142af69d88dSmrg      break;
143af69d88dSmrg   case GL_ALWAYS:
144af69d88dSmrg      Z_TEST(1);
145af69d88dSmrg      break;
146af69d88dSmrg   case GL_NEVER:
147af69d88dSmrg      memset(mask, 0, n * sizeof(GLubyte));
148af69d88dSmrg      break;
149af69d88dSmrg   default:
150af69d88dSmrg      _mesa_problem(ctx, "Bad depth func in depth_test_span32");
1517117f1b4Smrg   }
1527117f1b4Smrg
1537117f1b4Smrg   return passed;
1547117f1b4Smrg}
1557117f1b4Smrg
1567117f1b4Smrg
1574a49301eSmrg/**
1584a49301eSmrg * Clamp fragment Z values to the depth near/far range (glDepthRange()).
1594a49301eSmrg * This is used when GL_ARB_depth_clamp/GL_DEPTH_CLAMP is turned on.
1604a49301eSmrg * In that case, vertexes are not clipped against the near/far planes
1614a49301eSmrg * so rasterization will produce fragment Z values outside the usual
1624a49301eSmrg * [0,1] range.
1634a49301eSmrg */
1644a49301eSmrgvoid
1653464ebd5Sriastradh_swrast_depth_clamp_span( struct gl_context *ctx, SWspan *span )
1664a49301eSmrg{
1674a49301eSmrg   struct gl_framebuffer *fb = ctx->DrawBuffer;
1684a49301eSmrg   const GLuint count = span->end;
1694a49301eSmrg   GLint *zValues = (GLint *) span->array->z; /* sign change */
1704a49301eSmrg   GLint min, max;
1714a49301eSmrg   GLfloat min_f, max_f;
1724a49301eSmrg   GLuint i;
1734a49301eSmrg
174af69d88dSmrg   if (ctx->ViewportArray[0].Near < ctx->ViewportArray[0].Far) {
175af69d88dSmrg      min_f = ctx->ViewportArray[0].Near;
176af69d88dSmrg      max_f = ctx->ViewportArray[0].Far;
1774a49301eSmrg   } else {
178af69d88dSmrg      min_f = ctx->ViewportArray[0].Far;
179af69d88dSmrg      max_f = ctx->ViewportArray[0].Near;
1804a49301eSmrg   }
1814a49301eSmrg
1824a49301eSmrg   /* Convert floating point values in [0,1] to device Z coordinates in
1834a49301eSmrg    * [0, DepthMax].
184cdc920a0Smrg    * ex: If the Z buffer has 24 bits, DepthMax = 0xffffff.
1857ec681f3Smrg    *
1864a49301eSmrg    * XXX this all falls apart if we have 31 or more bits of Z because
1874a49301eSmrg    * the triangle rasterization code produces unsigned Z values.  Negative
1884a49301eSmrg    * vertex Z values come out as large fragment Z uints.
1894a49301eSmrg    */
1904a49301eSmrg   min = (GLint) (min_f * fb->_DepthMaxF);
1914a49301eSmrg   max = (GLint) (max_f * fb->_DepthMaxF);
1924a49301eSmrg   if (max < 0)
1934a49301eSmrg      max = 0x7fffffff; /* catch over flow for 30-bit z */
1944a49301eSmrg
1954a49301eSmrg   /* Note that we do the comparisons here using signed integers.
1964a49301eSmrg    */
1974a49301eSmrg   for (i = 0; i < count; i++) {
1984a49301eSmrg      if (zValues[i] < min)
1994a49301eSmrg	 zValues[i] = min;
2004a49301eSmrg      if (zValues[i] > max)
2014a49301eSmrg	 zValues[i] = max;
2024a49301eSmrg   }
2034a49301eSmrg}
2044a49301eSmrg
2054a49301eSmrg
206af69d88dSmrg/**
207af69d88dSmrg * Get array of 32-bit z values from the depth buffer.  With clipping.
208af69d88dSmrg * Note: the returned values are always in the range [0, 2^32-1].
2097117f1b4Smrg */
210af69d88dSmrgstatic void
211af69d88dSmrgget_z32_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
212af69d88dSmrg               GLuint count, const GLint x[], const GLint y[],
213af69d88dSmrg               GLuint zbuffer[])
2147117f1b4Smrg{
215af69d88dSmrg   struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
216af69d88dSmrg   const GLint w = rb->Width, h = rb->Height;
217af69d88dSmrg   const GLubyte *map = _swrast_pixel_address(rb, 0, 0);
218af69d88dSmrg   GLuint i;
2197117f1b4Smrg
220af69d88dSmrg   if (rb->Format == MESA_FORMAT_Z_UNORM32) {
221af69d88dSmrg      const GLint rowStride = srb->RowStride;
222af69d88dSmrg      for (i = 0; i < count; i++) {
223af69d88dSmrg         if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
224af69d88dSmrg            zbuffer[i] = *((GLuint *) (map + y[i] * rowStride + x[i] * 4));
225af69d88dSmrg         }
2267117f1b4Smrg      }
2277117f1b4Smrg   }
2287117f1b4Smrg   else {
229af69d88dSmrg      const GLint bpp = _mesa_get_format_bytes(rb->Format);
230af69d88dSmrg      const GLint rowStride = srb->RowStride;
231af69d88dSmrg      for (i = 0; i < count; i++) {
232af69d88dSmrg         if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
233af69d88dSmrg            const GLubyte *src = map + y[i] * rowStride+ x[i] * bpp;
234af69d88dSmrg            _mesa_unpack_uint_z_row(rb->Format, 1, src, &zbuffer[i]);
235af69d88dSmrg         }
2367117f1b4Smrg      }
2377117f1b4Smrg   }
2387117f1b4Smrg}
2397117f1b4Smrg
2407117f1b4Smrg
2417ec681f3Smrg/** Helper struct for MESA_FORMAT_Z32_FLOAT_S8X24_UINT */
2427ec681f3Smrgstruct z32f_x24s8
2437ec681f3Smrg{
2447ec681f3Smrg   float z;
2457ec681f3Smrg   uint32_t x24s8;
2467ec681f3Smrg};
2477ec681f3Smrg
2487ec681f3Smrg
2497ec681f3Smrg/**
2507ec681f3Smrg ** Pack uint Z pixels.  The incoming src value is always in
2517ec681f3Smrg ** the range [0, 2^32-1].
2527ec681f3Smrg **/
2537ec681f3Smrg
2547ec681f3Smrgstatic void
2557ec681f3Smrgpack_uint_S8_UINT_Z24_UNORM(const uint32_t *src, void *dst)
2567ec681f3Smrg{
2577ec681f3Smrg   /* don't disturb the stencil values */
2587ec681f3Smrg   uint32_t *d = ((uint32_t *) dst);
2597ec681f3Smrg   uint32_t s = *d & 0xff;
2607ec681f3Smrg   uint32_t z = *src & 0xffffff00;
2617ec681f3Smrg   *d = z | s;
2627ec681f3Smrg}
2637ec681f3Smrg
2647ec681f3Smrgstatic void
2657ec681f3Smrgpack_uint_Z24_UNORM_S8_UINT(const uint32_t *src, void *dst)
2667ec681f3Smrg{
2677ec681f3Smrg   /* don't disturb the stencil values */
2687ec681f3Smrg   uint32_t *d = ((uint32_t *) dst);
2697ec681f3Smrg   uint32_t s = *d & 0xff000000;
2707ec681f3Smrg   uint32_t z = *src >> 8;
2717ec681f3Smrg   *d = s | z;
2727ec681f3Smrg}
2737ec681f3Smrg
2747ec681f3Smrgstatic void
2757ec681f3Smrgpack_uint_Z_UNORM16(const uint32_t *src, void *dst)
2767ec681f3Smrg{
2777ec681f3Smrg   uint16_t *d = ((uint16_t *) dst);
2787ec681f3Smrg   *d = *src >> 16;
2797ec681f3Smrg}
2807ec681f3Smrg
2817ec681f3Smrgstatic void
2827ec681f3Smrgpack_uint_Z_UNORM32(const uint32_t *src, void *dst)
2837ec681f3Smrg{
2847ec681f3Smrg   uint32_t *d = ((uint32_t *) dst);
2857ec681f3Smrg   *d = *src;
2867ec681f3Smrg}
2877ec681f3Smrg
2887ec681f3Smrg/**
2897ec681f3Smrg ** Pack uint to Z_FLOAT32 or Z_FLOAT32_X24S8.
2907ec681f3Smrg **/
2917ec681f3Smrg
2927ec681f3Smrgstatic void
2937ec681f3Smrgpack_uint_Z_FLOAT32(const uint32_t *src, void *dst)
2947ec681f3Smrg{
2957ec681f3Smrg   float *d = ((float *) dst);
2967ec681f3Smrg   const double scale = 1.0 / (double) 0xffffffff;
2977ec681f3Smrg   *d = (float) (*src * scale);
2987ec681f3Smrg   assert(*d >= 0.0f);
2997ec681f3Smrg   assert(*d <= 1.0f);
3007ec681f3Smrg}
3017ec681f3Smrg
3027ec681f3Smrg/** Pack a uint32_t Z value to dest address */
3037ec681f3Smrgtypedef void (*mesa_pack_uint_z_func)(const uint32_t *src, void *dst);
3047ec681f3Smrg
3057ec681f3Smrgstatic mesa_pack_uint_z_func
3067ec681f3Smrgget_pack_uint_z_func(mesa_format format)
3077ec681f3Smrg{
3087ec681f3Smrg   switch (format) {
3097ec681f3Smrg   case MESA_FORMAT_S8_UINT_Z24_UNORM:
3107ec681f3Smrg   case MESA_FORMAT_X8_UINT_Z24_UNORM:
3117ec681f3Smrg      return pack_uint_S8_UINT_Z24_UNORM;
3127ec681f3Smrg   case MESA_FORMAT_Z24_UNORM_S8_UINT:
3137ec681f3Smrg   case MESA_FORMAT_Z24_UNORM_X8_UINT:
3147ec681f3Smrg      return pack_uint_Z24_UNORM_S8_UINT;
3157ec681f3Smrg   case MESA_FORMAT_Z_UNORM16:
3167ec681f3Smrg      return pack_uint_Z_UNORM16;
3177ec681f3Smrg   case MESA_FORMAT_Z_UNORM32:
3187ec681f3Smrg      return pack_uint_Z_UNORM32;
3197ec681f3Smrg   case MESA_FORMAT_Z_FLOAT32:
3207ec681f3Smrg   case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
3217ec681f3Smrg      return pack_uint_Z_FLOAT32;
3227ec681f3Smrg   default:
3237ec681f3Smrg      unreachable("unexpected format in get_pack_uint_z_func()");
3247ec681f3Smrg   }
3257ec681f3Smrg}
3267ec681f3Smrg
327af69d88dSmrg/**
328af69d88dSmrg * Put an array of 32-bit z values into the depth buffer.
329af69d88dSmrg * Note: the z values are always in the range [0, 2^32-1].
3307117f1b4Smrg */
3317117f1b4Smrgstatic void
332af69d88dSmrgput_z32_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
333af69d88dSmrg               GLuint count, const GLint x[], const GLint y[],
334af69d88dSmrg               const GLuint zvalues[], const GLubyte mask[])
3357117f1b4Smrg{
336af69d88dSmrg   struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
337af69d88dSmrg   const GLint w = rb->Width, h = rb->Height;
338af69d88dSmrg   GLubyte *map = _swrast_pixel_address(rb, 0, 0);
339af69d88dSmrg   GLuint i;
3407117f1b4Smrg
341af69d88dSmrg   if (rb->Format == MESA_FORMAT_Z_UNORM32) {
342af69d88dSmrg      const GLint rowStride = srb->RowStride;
343af69d88dSmrg      for (i = 0; i < count; i++) {
344af69d88dSmrg         if (mask[i] && x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
345af69d88dSmrg            GLuint *dst = (GLuint *) (map + y[i] * rowStride + x[i] * 4);
346af69d88dSmrg            *dst = zvalues[i];
347af69d88dSmrg         }
348af69d88dSmrg      }
349af69d88dSmrg   }
350af69d88dSmrg   else {
3517ec681f3Smrg      mesa_pack_uint_z_func packZ = get_pack_uint_z_func(rb->Format);
352af69d88dSmrg      const GLint bpp = _mesa_get_format_bytes(rb->Format);
353af69d88dSmrg      const GLint rowStride = srb->RowStride;
354af69d88dSmrg      for (i = 0; i < count; i++) {
355af69d88dSmrg         if (mask[i] && x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
356af69d88dSmrg            void *dst = map + y[i] * rowStride + x[i] * bpp;
357af69d88dSmrg            packZ(zvalues + i, dst);
358af69d88dSmrg         }
359af69d88dSmrg      }
3607117f1b4Smrg   }
3617117f1b4Smrg}
3627117f1b4Smrg
3637117f1b4Smrg
364af69d88dSmrg/**
365af69d88dSmrg * Apply depth (Z) buffer testing to the span.
366af69d88dSmrg * \return approx number of pixels that passed (only zero is reliable)
367af69d88dSmrg */
368af69d88dSmrgGLuint
369af69d88dSmrg_swrast_depth_test_span(struct gl_context *ctx, SWspan *span)
3707117f1b4Smrg{
3717117f1b4Smrg   struct gl_framebuffer *fb = ctx->DrawBuffer;
372af69d88dSmrg   struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
373af69d88dSmrg   const GLint bpp = _mesa_get_format_bytes(rb->Format);
374af69d88dSmrg   void *zStart;
3757117f1b4Smrg   const GLuint count = span->end;
376af69d88dSmrg   const GLuint *fragZ = span->array->z;
3777117f1b4Smrg   GLubyte *mask = span->array->mask;
378af69d88dSmrg   void *zBufferVals;
379af69d88dSmrg   GLuint *zBufferTemp = NULL;
380af69d88dSmrg   GLuint passed;
381af69d88dSmrg   GLuint zBits = _mesa_get_format_bits(rb->Format, GL_DEPTH_BITS);
382af69d88dSmrg   GLboolean ztest16 = GL_FALSE;
3837117f1b4Smrg
384af69d88dSmrg   if (span->arrayMask & SPAN_XY)
385af69d88dSmrg      zStart = NULL;
386af69d88dSmrg   else
387af69d88dSmrg      zStart = _swrast_pixel_address(rb, span->x, span->y);
388af69d88dSmrg
389af69d88dSmrg   if (rb->Format == MESA_FORMAT_Z_UNORM16 && !(span->arrayMask & SPAN_XY)) {
390af69d88dSmrg      /* directly read/write row of 16-bit Z values */
391af69d88dSmrg      zBufferVals = zStart;
392af69d88dSmrg      ztest16 = GL_TRUE;
393af69d88dSmrg   }
394af69d88dSmrg   else if (rb->Format == MESA_FORMAT_Z_UNORM32 && !(span->arrayMask & SPAN_XY)) {
395af69d88dSmrg      /* directly read/write row of 32-bit Z values */
396af69d88dSmrg      zBufferVals = zStart;
397af69d88dSmrg   }
398af69d88dSmrg   else {
399af69d88dSmrg      /* copy Z buffer values into temp buffer (32-bit Z values) */
400af69d88dSmrg      zBufferTemp = malloc(count * sizeof(GLuint));
401af69d88dSmrg      if (!zBufferTemp)
402af69d88dSmrg         return 0;
403af69d88dSmrg
404af69d88dSmrg      if (span->arrayMask & SPAN_XY) {
405af69d88dSmrg         get_z32_values(ctx, rb, count,
406af69d88dSmrg                        span->array->x, span->array->y, zBufferTemp);
4077117f1b4Smrg      }
4087117f1b4Smrg      else {
409af69d88dSmrg         _mesa_unpack_uint_z_row(rb->Format, count, zStart, zBufferTemp);
4107117f1b4Smrg      }
411af69d88dSmrg
412af69d88dSmrg      if (zBits == 24) {
413af69d88dSmrg         GLuint i;
414af69d88dSmrg         /* Convert depth buffer values from 32 to 24 bits to match the
415af69d88dSmrg          * fragment Z values generated by rasterization.
416af69d88dSmrg          */
417af69d88dSmrg         for (i = 0; i < count; i++) {
418af69d88dSmrg            zBufferTemp[i] >>= 8;
419af69d88dSmrg         }
420af69d88dSmrg      }
421af69d88dSmrg      else if (zBits == 16) {
422af69d88dSmrg         GLuint i;
423af69d88dSmrg         /* Convert depth buffer values from 32 to 16 bits */
424af69d88dSmrg         for (i = 0; i < count; i++) {
425af69d88dSmrg            zBufferTemp[i] >>= 16;
426af69d88dSmrg         }
4277117f1b4Smrg      }
4287117f1b4Smrg      else {
429af69d88dSmrg         assert(zBits == 32);
4307117f1b4Smrg      }
431af69d88dSmrg
432af69d88dSmrg      zBufferVals = zBufferTemp;
4337117f1b4Smrg   }
4347117f1b4Smrg
435af69d88dSmrg   /* do the depth test either with 16 or 32-bit values */
436af69d88dSmrg   if (ztest16)
437af69d88dSmrg      passed = depth_test_span16(ctx, count, zBufferVals, fragZ, mask);
438af69d88dSmrg   else
439af69d88dSmrg      passed = depth_test_span32(ctx, count, zBufferVals, fragZ, mask);
4407117f1b4Smrg
441af69d88dSmrg   if (zBufferTemp) {
442af69d88dSmrg      /* need to write temp Z values back into the buffer */
4437117f1b4Smrg
444af69d88dSmrg      /* Convert depth buffer values back to 32-bit values.  The least
445af69d88dSmrg       * significant bits don't matter since they'll get dropped when
446af69d88dSmrg       * they're packed back into the depth buffer.
447af69d88dSmrg       */
448af69d88dSmrg      if (zBits == 24) {
449af69d88dSmrg         GLuint i;
450af69d88dSmrg         for (i = 0; i < count; i++) {
451af69d88dSmrg            zBufferTemp[i] = (zBufferTemp[i] << 8);
452af69d88dSmrg         }
453af69d88dSmrg      }
454af69d88dSmrg      else if (zBits == 16) {
455af69d88dSmrg         GLuint i;
456af69d88dSmrg         for (i = 0; i < count; i++) {
457af69d88dSmrg            zBufferTemp[i] = zBufferTemp[i] << 16;
458af69d88dSmrg         }
459af69d88dSmrg      }
460af69d88dSmrg
461af69d88dSmrg      if (span->arrayMask & SPAN_XY) {
462af69d88dSmrg         /* random locations */
463af69d88dSmrg         put_z32_values(ctx, rb, count, span->array->x, span->array->y,
464af69d88dSmrg                        zBufferTemp, mask);
465af69d88dSmrg      }
466af69d88dSmrg      else {
467af69d88dSmrg         /* horizontal row */
4687ec681f3Smrg         mesa_pack_uint_z_func packZ = get_pack_uint_z_func(rb->Format);
469af69d88dSmrg         GLubyte *dst = zStart;
470af69d88dSmrg         GLuint i;
471af69d88dSmrg         for (i = 0; i < count; i++) {
472af69d88dSmrg            if (mask[i]) {
473af69d88dSmrg               packZ(&zBufferTemp[i], dst);
474af69d88dSmrg            }
475af69d88dSmrg            dst += bpp;
476af69d88dSmrg         }
477af69d88dSmrg      }
478af69d88dSmrg
479af69d88dSmrg      free(zBufferTemp);
480af69d88dSmrg   }
481af69d88dSmrg
482af69d88dSmrg   if (passed < count) {
483af69d88dSmrg      span->writeAll = GL_FALSE;
484af69d88dSmrg   }
485af69d88dSmrg   return passed;
4867117f1b4Smrg}
4877117f1b4Smrg
4887117f1b4Smrg
4897117f1b4Smrg/**
4907117f1b4Smrg * GL_EXT_depth_bounds_test extension.
4917117f1b4Smrg * Discard fragments depending on whether the corresponding Z-buffer
4927117f1b4Smrg * values are outside the depth bounds test range.
4937117f1b4Smrg * Note: we test the Z buffer values, not the fragment Z values!
4947117f1b4Smrg * \return GL_TRUE if any fragments pass, GL_FALSE if no fragments pass
4957117f1b4Smrg */
4967117f1b4SmrgGLboolean
4973464ebd5Sriastradh_swrast_depth_bounds_test( struct gl_context *ctx, SWspan *span )
4987117f1b4Smrg{
4997117f1b4Smrg   struct gl_framebuffer *fb = ctx->DrawBuffer;
500af69d88dSmrg   struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
501af69d88dSmrg   GLubyte *zStart;
50201e04c3fSmrg   GLuint zMin = (GLuint)((double)ctx->Depth.BoundsMin * 0xffffffff);
50301e04c3fSmrg   GLuint zMax = (GLuint)((double)ctx->Depth.BoundsMax * 0xffffffff);
5047117f1b4Smrg   GLubyte *mask = span->array->mask;
5057117f1b4Smrg   const GLuint count = span->end;
5067117f1b4Smrg   GLuint i;
5077117f1b4Smrg   GLboolean anyPass = GL_FALSE;
508af69d88dSmrg   GLuint *zBufferTemp;
509af69d88dSmrg   const GLuint *zBufferVals;
5107117f1b4Smrg
511af69d88dSmrg   zBufferTemp = malloc(count * sizeof(GLuint));
512af69d88dSmrg   if (!zBufferTemp) {
513af69d88dSmrg      /* don't generate a stream of OUT_OF_MEMORY errors here */
514af69d88dSmrg      return GL_FALSE;
515af69d88dSmrg   }
5167117f1b4Smrg
517af69d88dSmrg   if (span->arrayMask & SPAN_XY)
518af69d88dSmrg      zStart = NULL;
519af69d88dSmrg   else
520af69d88dSmrg      zStart = _swrast_pixel_address(rb, span->x, span->y);
521af69d88dSmrg
522af69d88dSmrg   if (rb->Format == MESA_FORMAT_Z_UNORM32 && !(span->arrayMask & SPAN_XY)) {
523af69d88dSmrg      /* directly access 32-bit values in the depth buffer */
524af69d88dSmrg      zBufferVals = (const GLuint *) zStart;
5257117f1b4Smrg   }
5267117f1b4Smrg   else {
52701e04c3fSmrg      /* Round the bounds to the precision of the zbuffer. */
52801e04c3fSmrg      if (rb->Format == MESA_FORMAT_Z_UNORM16) {
52901e04c3fSmrg         zMin = (zMin & 0xffff0000) | (zMin >> 16);
53001e04c3fSmrg         zMax = (zMax & 0xffff0000) | (zMax >> 16);
53101e04c3fSmrg      } else {
53201e04c3fSmrg         /* 24 bits */
53301e04c3fSmrg         zMin = (zMin & 0xffffff00) | (zMin >> 24);
53401e04c3fSmrg         zMax = (zMax & 0xffffff00) | (zMax >> 24);
53501e04c3fSmrg      }
53601e04c3fSmrg
537af69d88dSmrg      /* unpack Z values into a temporary array */
5387117f1b4Smrg      if (span->arrayMask & SPAN_XY) {
539af69d88dSmrg         get_z32_values(ctx, rb, count, span->array->x, span->array->y,
540af69d88dSmrg                        zBufferTemp);
5417117f1b4Smrg      }
5427117f1b4Smrg      else {
543af69d88dSmrg         _mesa_unpack_uint_z_row(rb->Format, count, zStart, zBufferTemp);
5447117f1b4Smrg      }
545af69d88dSmrg      zBufferVals = zBufferTemp;
546af69d88dSmrg   }
5477117f1b4Smrg
548af69d88dSmrg   /* Now do the tests */
549af69d88dSmrg   for (i = 0; i < count; i++) {
550af69d88dSmrg      if (mask[i]) {
551af69d88dSmrg         if (zBufferVals[i] < zMin || zBufferVals[i] > zMax)
552af69d88dSmrg            mask[i] = GL_FALSE;
553af69d88dSmrg         else
554af69d88dSmrg            anyPass = GL_TRUE;
5557117f1b4Smrg      }
5567117f1b4Smrg   }
5577117f1b4Smrg
558af69d88dSmrg   free(zBufferTemp);
559af69d88dSmrg
5607117f1b4Smrg   return anyPass;
5617117f1b4Smrg}
5627117f1b4Smrg
5637117f1b4Smrg
5647117f1b4Smrg
5657117f1b4Smrg/**********************************************************************/
5667117f1b4Smrg/*****                      Read Depth Buffer                     *****/
5677117f1b4Smrg/**********************************************************************/
5687117f1b4Smrg
5697117f1b4Smrg
5707117f1b4Smrg/**
5717117f1b4Smrg * Read a span of depth values from the given depth renderbuffer, returning
5727117f1b4Smrg * the values as GLfloats.
5737117f1b4Smrg * This function does clipping to prevent reading outside the depth buffer's
574af69d88dSmrg * bounds.
5757117f1b4Smrg */
5767117f1b4Smrgvoid
577af69d88dSmrg_swrast_read_depth_span_float(struct gl_context *ctx,
578af69d88dSmrg                              struct gl_renderbuffer *rb,
579af69d88dSmrg                              GLint n, GLint x, GLint y, GLfloat depth[])
5807117f1b4Smrg{
5817117f1b4Smrg   if (!rb) {
5827117f1b4Smrg      /* really only doing this to prevent FP exceptions later */
583cdc920a0Smrg      memset(depth, 0, n * sizeof(GLfloat));
5844a49301eSmrg      return;
5857117f1b4Smrg   }
5867117f1b4Smrg
5877117f1b4Smrg   if (y < 0 || y >= (GLint) rb->Height ||
5887117f1b4Smrg       x + n <= 0 || x >= (GLint) rb->Width) {
5897117f1b4Smrg      /* span is completely outside framebuffer */
590cdc920a0Smrg      memset(depth, 0, n * sizeof(GLfloat));
5917117f1b4Smrg      return;
5927117f1b4Smrg   }
5937117f1b4Smrg
5947117f1b4Smrg   if (x < 0) {
5957117f1b4Smrg      GLint dx = -x;
5967117f1b4Smrg      GLint i;
5977117f1b4Smrg      for (i = 0; i < dx; i++)
5987117f1b4Smrg         depth[i] = 0.0;
5997117f1b4Smrg      x = 0;
6007117f1b4Smrg      n -= dx;
6017117f1b4Smrg      depth += dx;
6027117f1b4Smrg   }
6037117f1b4Smrg   if (x + n > (GLint) rb->Width) {
6047117f1b4Smrg      GLint dx = x + n - (GLint) rb->Width;
6057117f1b4Smrg      GLint i;
6067117f1b4Smrg      for (i = 0; i < dx; i++)
6077117f1b4Smrg         depth[n - i - 1] = 0.0;
6087117f1b4Smrg      n -= dx;
6097117f1b4Smrg   }
6107117f1b4Smrg   if (n <= 0) {
6117117f1b4Smrg      return;
6127117f1b4Smrg   }
6137117f1b4Smrg
614af69d88dSmrg   _mesa_unpack_float_z_row(rb->Format, n, _swrast_pixel_address(rb, x, y),
615af69d88dSmrg                            depth);
6167117f1b4Smrg}
6177117f1b4Smrg
6187117f1b4Smrg
6197117f1b4Smrg/**
620af69d88dSmrg * Clear the given z/depth renderbuffer.  If the buffer is a combined
621af69d88dSmrg * depth+stencil buffer, only the Z bits will be touched.
6227117f1b4Smrg */
6237117f1b4Smrgvoid
624af69d88dSmrg_swrast_clear_depth_buffer(struct gl_context *ctx)
6257117f1b4Smrg{
626af69d88dSmrg   struct gl_renderbuffer *rb =
627af69d88dSmrg      ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
628af69d88dSmrg   GLint x, y, width, height;
629af69d88dSmrg   GLubyte *map;
630af69d88dSmrg   GLint rowStride, i, j;
631af69d88dSmrg   GLbitfield mapMode;
6324a49301eSmrg
633af69d88dSmrg   if (!rb || !ctx->Depth.Mask) {
634af69d88dSmrg      /* no depth buffer, or writing to it is disabled */
6354a49301eSmrg      return;
6367117f1b4Smrg   }
6377117f1b4Smrg
638af69d88dSmrg   /* compute region to clear */
639af69d88dSmrg   x = ctx->DrawBuffer->_Xmin;
640af69d88dSmrg   y = ctx->DrawBuffer->_Ymin;
641af69d88dSmrg   width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
642af69d88dSmrg   height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
6437117f1b4Smrg
644af69d88dSmrg   mapMode = GL_MAP_WRITE_BIT;
645af69d88dSmrg   if (rb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT ||
646af69d88dSmrg       rb->Format == MESA_FORMAT_Z24_UNORM_X8_UINT ||
647af69d88dSmrg       rb->Format == MESA_FORMAT_S8_UINT_Z24_UNORM ||
648af69d88dSmrg       rb->Format == MESA_FORMAT_X8_UINT_Z24_UNORM) {
649af69d88dSmrg      mapMode |= GL_MAP_READ_BIT;
6507117f1b4Smrg   }
6517117f1b4Smrg
652af69d88dSmrg   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
65301e04c3fSmrg                               mapMode, &map, &rowStride,
65401e04c3fSmrg                               ctx->DrawBuffer->FlipY);
655af69d88dSmrg   if (!map) {
656af69d88dSmrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(depth)");
6577117f1b4Smrg      return;
6587117f1b4Smrg   }
6597117f1b4Smrg
660af69d88dSmrg   switch (rb->Format) {
661af69d88dSmrg   case MESA_FORMAT_Z_UNORM16:
662af69d88dSmrg      {
663af69d88dSmrg         GLfloat clear = (GLfloat) ctx->Depth.Clear;
664af69d88dSmrg         GLushort clearVal = 0;
665af69d88dSmrg         _mesa_pack_float_z_row(rb->Format, 1, &clear, &clearVal);
666af69d88dSmrg         if (clearVal == 0xffff && width * 2 == rowStride) {
667af69d88dSmrg            /* common case */
668af69d88dSmrg            memset(map, 0xff, width * height * 2);
669af69d88dSmrg         }
670af69d88dSmrg         else {
671af69d88dSmrg            for (i = 0; i < height; i++) {
672af69d88dSmrg               GLushort *row = (GLushort *) map;
673af69d88dSmrg               for (j = 0; j < width; j++) {
674af69d88dSmrg                  row[j] = clearVal;
675af69d88dSmrg               }
676af69d88dSmrg               map += rowStride;
677af69d88dSmrg            }
6787117f1b4Smrg         }
6797117f1b4Smrg      }
680af69d88dSmrg      break;
681af69d88dSmrg   case MESA_FORMAT_Z_UNORM32:
682af69d88dSmrg   case MESA_FORMAT_Z_FLOAT32:
683af69d88dSmrg      {
684af69d88dSmrg         GLfloat clear = (GLfloat) ctx->Depth.Clear;
685af69d88dSmrg         GLuint clearVal = 0;
686af69d88dSmrg         _mesa_pack_float_z_row(rb->Format, 1, &clear, &clearVal);
687af69d88dSmrg         for (i = 0; i < height; i++) {
688af69d88dSmrg            GLuint *row = (GLuint *) map;
689af69d88dSmrg            for (j = 0; j < width; j++) {
690af69d88dSmrg               row[j] = clearVal;
691af69d88dSmrg            }
692af69d88dSmrg            map += rowStride;
6937117f1b4Smrg         }
6947117f1b4Smrg      }
695af69d88dSmrg      break;
696af69d88dSmrg   case MESA_FORMAT_Z24_UNORM_S8_UINT:
697af69d88dSmrg   case MESA_FORMAT_Z24_UNORM_X8_UINT:
698af69d88dSmrg   case MESA_FORMAT_S8_UINT_Z24_UNORM:
699af69d88dSmrg   case MESA_FORMAT_X8_UINT_Z24_UNORM:
700af69d88dSmrg      {
701af69d88dSmrg         GLfloat clear = (GLfloat) ctx->Depth.Clear;
702af69d88dSmrg         GLuint clearVal = 0;
703af69d88dSmrg         GLuint mask;
704af69d88dSmrg
705af69d88dSmrg         if (rb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT ||
706af69d88dSmrg             rb->Format == MESA_FORMAT_Z24_UNORM_X8_UINT)
707af69d88dSmrg            mask = 0xff000000;
708af69d88dSmrg         else
709af69d88dSmrg            mask = 0xff;
710af69d88dSmrg
711af69d88dSmrg         _mesa_pack_float_z_row(rb->Format, 1, &clear, &clearVal);
712af69d88dSmrg         for (i = 0; i < height; i++) {
713af69d88dSmrg            GLuint *row = (GLuint *) map;
714af69d88dSmrg            for (j = 0; j < width; j++) {
715af69d88dSmrg               row[j] = (row[j] & mask) | clearVal;
716af69d88dSmrg            }
717af69d88dSmrg            map += rowStride;
7187117f1b4Smrg         }
719af69d88dSmrg
7207117f1b4Smrg      }
721af69d88dSmrg      break;
722af69d88dSmrg   case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
723af69d88dSmrg      /* XXX untested */
724af69d88dSmrg      {
725af69d88dSmrg         GLfloat clearVal = (GLfloat) ctx->Depth.Clear;
726af69d88dSmrg         for (i = 0; i < height; i++) {
727af69d88dSmrg            GLfloat *row = (GLfloat *) map;
728af69d88dSmrg            for (j = 0; j < width; j++) {
729af69d88dSmrg               row[j * 2] = clearVal;
730af69d88dSmrg            }
731af69d88dSmrg            map += rowStride;
732af69d88dSmrg         }
733af69d88dSmrg      }
734af69d88dSmrg      break;
735af69d88dSmrg   default:
736af69d88dSmrg      _mesa_problem(ctx, "Unexpected depth buffer format %s"
737af69d88dSmrg                    " in _swrast_clear_depth_buffer()",
738af69d88dSmrg                    _mesa_get_format_name(rb->Format));
7397117f1b4Smrg   }
740af69d88dSmrg
741af69d88dSmrg   ctx->Driver.UnmapRenderbuffer(ctx, rb);
7427117f1b4Smrg}
7437117f1b4Smrg
7447117f1b4Smrg
7457117f1b4Smrg
746af69d88dSmrg
7477117f1b4Smrg/**
748af69d88dSmrg * Clear both depth and stencil values in a combined depth+stencil buffer.
7497117f1b4Smrg */
7507117f1b4Smrgvoid
751af69d88dSmrg_swrast_clear_depth_stencil_buffer(struct gl_context *ctx)
7527117f1b4Smrg{
753af69d88dSmrg   const GLubyte stencilBits = ctx->DrawBuffer->Visual.stencilBits;
754af69d88dSmrg   const GLuint writeMask = ctx->Stencil.WriteMask[0];
755af69d88dSmrg   const GLuint stencilMax = (1 << stencilBits) - 1;
756af69d88dSmrg   struct gl_renderbuffer *rb =
757af69d88dSmrg      ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
7587117f1b4Smrg   GLint x, y, width, height;
759af69d88dSmrg   GLbitfield mapMode;
760af69d88dSmrg   GLubyte *map;
761af69d88dSmrg   GLint rowStride, i, j;
7627117f1b4Smrg
763af69d88dSmrg   /* check that we really have a combined depth+stencil buffer */
764af69d88dSmrg   assert(rb == ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer);
7657117f1b4Smrg
7667117f1b4Smrg   /* compute region to clear */
7677117f1b4Smrg   x = ctx->DrawBuffer->_Xmin;
7687117f1b4Smrg   y = ctx->DrawBuffer->_Ymin;
7697117f1b4Smrg   width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
7707117f1b4Smrg   height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
7717117f1b4Smrg
772af69d88dSmrg   mapMode = GL_MAP_WRITE_BIT;
773af69d88dSmrg   if ((writeMask & stencilMax) != stencilMax) {
774af69d88dSmrg      /* need to mask stencil values */
775af69d88dSmrg      mapMode |= GL_MAP_READ_BIT;
776af69d88dSmrg   }
777af69d88dSmrg
778af69d88dSmrg   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
77901e04c3fSmrg                               mapMode, &map, &rowStride,
78001e04c3fSmrg                               ctx->DrawBuffer->FlipY);
781af69d88dSmrg   if (!map) {
782af69d88dSmrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(depth+stencil)");
783af69d88dSmrg      return;
784af69d88dSmrg   }
785af69d88dSmrg
786af69d88dSmrg   switch (rb->Format) {
787af69d88dSmrg   case MESA_FORMAT_Z24_UNORM_S8_UINT:
788af69d88dSmrg   case MESA_FORMAT_S8_UINT_Z24_UNORM:
789af69d88dSmrg      {
790af69d88dSmrg         GLfloat zClear = (GLfloat) ctx->Depth.Clear;
791af69d88dSmrg         GLuint clear = 0, mask;
792af69d88dSmrg
793af69d88dSmrg         _mesa_pack_float_z_row(rb->Format, 1, &zClear, &clear);
794af69d88dSmrg
795af69d88dSmrg         if (rb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT) {
796af69d88dSmrg            mask = ((~writeMask) & 0xff) << 24;
797af69d88dSmrg            clear |= (ctx->Stencil.Clear & writeMask & 0xff) << 24;
7987117f1b4Smrg         }
7997117f1b4Smrg         else {
800af69d88dSmrg            mask = ((~writeMask) & 0xff);
801af69d88dSmrg            clear |= (ctx->Stencil.Clear & writeMask & 0xff);
802af69d88dSmrg         }
803af69d88dSmrg
804af69d88dSmrg         for (i = 0; i < height; i++) {
805af69d88dSmrg            GLuint *row = (GLuint *) map;
806af69d88dSmrg            if (mask != 0x0) {
8077117f1b4Smrg               for (j = 0; j < width; j++) {
808af69d88dSmrg                  row[j] = (row[j] & mask) | clear;
8097117f1b4Smrg               }
8107117f1b4Smrg            }
811af69d88dSmrg            else {
812af69d88dSmrg               for (j = 0; j < width; j++) {
813af69d88dSmrg                  row[j] = clear;
814af69d88dSmrg               }
815af69d88dSmrg            }
816af69d88dSmrg            map += rowStride;
8177117f1b4Smrg         }
8187117f1b4Smrg      }
819af69d88dSmrg      break;
820af69d88dSmrg   case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
821af69d88dSmrg      /* XXX untested */
822af69d88dSmrg      {
823af69d88dSmrg         const GLfloat zClear = (GLfloat) ctx->Depth.Clear;
824af69d88dSmrg         const GLuint sClear = ctx->Stencil.Clear & writeMask;
825af69d88dSmrg         const GLuint sMask = (~writeMask) & 0xff;
8267117f1b4Smrg         for (i = 0; i < height; i++) {
827af69d88dSmrg            GLfloat *zRow = (GLfloat *) map;
828af69d88dSmrg            GLuint *sRow = (GLuint *) map;
8297117f1b4Smrg            for (j = 0; j < width; j++) {
830af69d88dSmrg               zRow[j * 2 + 0] = zClear;
8317117f1b4Smrg            }
832af69d88dSmrg            if (sMask != 0) {
833af69d88dSmrg               for (j = 0; j < width; j++) {
834af69d88dSmrg                  sRow[j * 2 + 1] = (sRow[j * 2 + 1] & sMask) | sClear;
835af69d88dSmrg               }
836af69d88dSmrg            }
837af69d88dSmrg            else {
838af69d88dSmrg               for (j = 0; j < width; j++) {
839af69d88dSmrg                  sRow[j * 2 + 1] = sClear;
840af69d88dSmrg               }
841af69d88dSmrg            }
842af69d88dSmrg            map += rowStride;
8437117f1b4Smrg         }
8447117f1b4Smrg      }
845af69d88dSmrg      break;
846af69d88dSmrg   default:
847af69d88dSmrg      _mesa_problem(ctx, "Unexpected depth buffer format %s"
848af69d88dSmrg                    " in _swrast_clear_depth_buffer()",
849af69d88dSmrg                    _mesa_get_format_name(rb->Format));
8507117f1b4Smrg   }
851af69d88dSmrg
852af69d88dSmrg   ctx->Driver.UnmapRenderbuffer(ctx, rb);
853af69d88dSmrg
8547117f1b4Smrg}
855