1e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library
37cb723a3fd4d90ad6efa5f440e5e39f8aaa9f79cBrian Paul * Version:  7.2.1
422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
57cb723a3fd4d90ad6efa5f440e5e39f8aaa9f79cBrian Paul * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
7e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
8e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"),
9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation
10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the
12e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions:
1322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included
15e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software.
1622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
25e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
26bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h"
27bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/context.h"
2845e76d2665b38ba3787548310efc59e969124c01Brian Paul#include "main/formats.h"
298e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul#include "main/format_unpack.h"
30fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul#include "main/format_pack.h"
31bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/macros.h"
32bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/imports.h"
33e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
34242fd9df3b2266402b3f6b20447798fb3bf57d53Brian Paul#include "s_context.h"
35e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_depth.h"
3667074332728acba86da7630353673b458713bb8aBrian Paul#include "s_span.h"
37e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
38e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
3929a9983969f43df5f75483c8196df1963d89cb97Brian Paul
4029a9983969f43df5f75483c8196df1963d89cb97Brian Paul#define Z_TEST(COMPARE)                      \
4129a9983969f43df5f75483c8196df1963d89cb97Brian Paul   do {                                      \
4229a9983969f43df5f75483c8196df1963d89cb97Brian Paul      GLuint i;                              \
4329a9983969f43df5f75483c8196df1963d89cb97Brian Paul      for (i = 0; i < n; i++) {              \
4429a9983969f43df5f75483c8196df1963d89cb97Brian Paul         if (mask[i]) {                      \
4529a9983969f43df5f75483c8196df1963d89cb97Brian Paul            if (COMPARE) {                   \
4629a9983969f43df5f75483c8196df1963d89cb97Brian Paul               /* pass */                    \
4729a9983969f43df5f75483c8196df1963d89cb97Brian Paul               if (write) {                  \
4829a9983969f43df5f75483c8196df1963d89cb97Brian Paul                  zbuffer[i] = zfrag[i];     \
4929a9983969f43df5f75483c8196df1963d89cb97Brian Paul               }                             \
5029a9983969f43df5f75483c8196df1963d89cb97Brian Paul               passed++;                     \
5129a9983969f43df5f75483c8196df1963d89cb97Brian Paul            }                                \
5229a9983969f43df5f75483c8196df1963d89cb97Brian Paul            else {                           \
5329a9983969f43df5f75483c8196df1963d89cb97Brian Paul               /* fail */                    \
5429a9983969f43df5f75483c8196df1963d89cb97Brian Paul               mask[i] = 0;                  \
5529a9983969f43df5f75483c8196df1963d89cb97Brian Paul            }                                \
5629a9983969f43df5f75483c8196df1963d89cb97Brian Paul         }                                   \
5729a9983969f43df5f75483c8196df1963d89cb97Brian Paul      }                                      \
5829a9983969f43df5f75483c8196df1963d89cb97Brian Paul   } while (0)
5929a9983969f43df5f75483c8196df1963d89cb97Brian Paul
6029a9983969f43df5f75483c8196df1963d89cb97Brian Paul
6179c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
6229a9983969f43df5f75483c8196df1963d89cb97Brian Paul * Do depth test for an array of 16-bit Z values.
6329a9983969f43df5f75483c8196df1963d89cb97Brian Paul * @param zbuffer  array of Z buffer values (16-bit)
6429a9983969f43df5f75483c8196df1963d89cb97Brian Paul * @param zfrag  array of fragment Z values (use 16-bit in 32-bit uint)
6529a9983969f43df5f75483c8196df1963d89cb97Brian Paul * @param mask  which fragments are alive, killed afterward
6629a9983969f43df5f75483c8196df1963d89cb97Brian Paul * @return  number of fragments which pass the test.
67e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
68e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic GLuint
69f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergdepth_test_span16( struct gl_context *ctx, GLuint n,
7029a9983969f43df5f75483c8196df1963d89cb97Brian Paul                   GLushort zbuffer[], const GLuint zfrag[], GLubyte mask[] )
71e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
7229a9983969f43df5f75483c8196df1963d89cb97Brian Paul   const GLboolean write = ctx->Depth.Mask;
73e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint passed = 0;
74e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
75e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* switch cases ordered from most frequent to less frequent */
76e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   switch (ctx->Depth.Func) {
7729a9983969f43df5f75483c8196df1963d89cb97Brian Paul   case GL_LESS:
7829a9983969f43df5f75483c8196df1963d89cb97Brian Paul      Z_TEST(zfrag[i] < zbuffer[i]);
7929a9983969f43df5f75483c8196df1963d89cb97Brian Paul      break;
8029a9983969f43df5f75483c8196df1963d89cb97Brian Paul   case GL_LEQUAL:
8129a9983969f43df5f75483c8196df1963d89cb97Brian Paul      Z_TEST(zfrag[i] <= zbuffer[i]);
8229a9983969f43df5f75483c8196df1963d89cb97Brian Paul      break;
8329a9983969f43df5f75483c8196df1963d89cb97Brian Paul   case GL_GEQUAL:
8429a9983969f43df5f75483c8196df1963d89cb97Brian Paul      Z_TEST(zfrag[i] >= zbuffer[i]);
8529a9983969f43df5f75483c8196df1963d89cb97Brian Paul      break;
8629a9983969f43df5f75483c8196df1963d89cb97Brian Paul   case GL_GREATER:
8729a9983969f43df5f75483c8196df1963d89cb97Brian Paul      Z_TEST(zfrag[i] > zbuffer[i]);
8829a9983969f43df5f75483c8196df1963d89cb97Brian Paul      break;
8929a9983969f43df5f75483c8196df1963d89cb97Brian Paul   case GL_NOTEQUAL:
9029a9983969f43df5f75483c8196df1963d89cb97Brian Paul      Z_TEST(zfrag[i] != zbuffer[i]);
9129a9983969f43df5f75483c8196df1963d89cb97Brian Paul      break;
9229a9983969f43df5f75483c8196df1963d89cb97Brian Paul   case GL_EQUAL:
9329a9983969f43df5f75483c8196df1963d89cb97Brian Paul      Z_TEST(zfrag[i] == zbuffer[i]);
9429a9983969f43df5f75483c8196df1963d89cb97Brian Paul      break;
9529a9983969f43df5f75483c8196df1963d89cb97Brian Paul   case GL_ALWAYS:
9629a9983969f43df5f75483c8196df1963d89cb97Brian Paul      Z_TEST(1);
9729a9983969f43df5f75483c8196df1963d89cb97Brian Paul      break;
9829a9983969f43df5f75483c8196df1963d89cb97Brian Paul   case GL_NEVER:
9929a9983969f43df5f75483c8196df1963d89cb97Brian Paul      memset(mask, 0, n * sizeof(GLubyte));
10029a9983969f43df5f75483c8196df1963d89cb97Brian Paul      break;
10129a9983969f43df5f75483c8196df1963d89cb97Brian Paul   default:
10229a9983969f43df5f75483c8196df1963d89cb97Brian Paul      _mesa_problem(ctx, "Bad depth func in depth_test_span16");
103e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
104e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
105e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   return passed;
106e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
107e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
108e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
10929a9983969f43df5f75483c8196df1963d89cb97Brian Paul/**
11029a9983969f43df5f75483c8196df1963d89cb97Brian Paul * Do depth test for an array of 32-bit Z values.
11129a9983969f43df5f75483c8196df1963d89cb97Brian Paul * @param zbuffer  array of Z buffer values (32-bit)
11229a9983969f43df5f75483c8196df1963d89cb97Brian Paul * @param zfrag  array of fragment Z values (use 32-bits in 32-bit uint)
11329a9983969f43df5f75483c8196df1963d89cb97Brian Paul * @param mask  which fragments are alive, killed afterward
11429a9983969f43df5f75483c8196df1963d89cb97Brian Paul * @return  number of fragments which pass the test.
11529a9983969f43df5f75483c8196df1963d89cb97Brian Paul */
116e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic GLuint
117f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergdepth_test_span32( struct gl_context *ctx, GLuint n,
11829a9983969f43df5f75483c8196df1963d89cb97Brian Paul                   GLuint zbuffer[], const GLuint zfrag[], GLubyte mask[])
119e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
12029a9983969f43df5f75483c8196df1963d89cb97Brian Paul   const GLboolean write = ctx->Depth.Mask;
121e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLuint passed = 0;
122e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
123e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* switch cases ordered from most frequent to less frequent */
124e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   switch (ctx->Depth.Func) {
12529a9983969f43df5f75483c8196df1963d89cb97Brian Paul   case GL_LESS:
12629a9983969f43df5f75483c8196df1963d89cb97Brian Paul      Z_TEST(zfrag[i] < zbuffer[i]);
12729a9983969f43df5f75483c8196df1963d89cb97Brian Paul      break;
12829a9983969f43df5f75483c8196df1963d89cb97Brian Paul   case GL_LEQUAL:
12929a9983969f43df5f75483c8196df1963d89cb97Brian Paul      Z_TEST(zfrag[i] <= zbuffer[i]);
13029a9983969f43df5f75483c8196df1963d89cb97Brian Paul      break;
13129a9983969f43df5f75483c8196df1963d89cb97Brian Paul   case GL_GEQUAL:
13229a9983969f43df5f75483c8196df1963d89cb97Brian Paul      Z_TEST(zfrag[i] >= zbuffer[i]);
13329a9983969f43df5f75483c8196df1963d89cb97Brian Paul      break;
13429a9983969f43df5f75483c8196df1963d89cb97Brian Paul   case GL_GREATER:
13529a9983969f43df5f75483c8196df1963d89cb97Brian Paul      Z_TEST(zfrag[i] > zbuffer[i]);
13629a9983969f43df5f75483c8196df1963d89cb97Brian Paul      break;
13729a9983969f43df5f75483c8196df1963d89cb97Brian Paul   case GL_NOTEQUAL:
13829a9983969f43df5f75483c8196df1963d89cb97Brian Paul      Z_TEST(zfrag[i] != zbuffer[i]);
13929a9983969f43df5f75483c8196df1963d89cb97Brian Paul      break;
14029a9983969f43df5f75483c8196df1963d89cb97Brian Paul   case GL_EQUAL:
14129a9983969f43df5f75483c8196df1963d89cb97Brian Paul      Z_TEST(zfrag[i] == zbuffer[i]);
14229a9983969f43df5f75483c8196df1963d89cb97Brian Paul      break;
14329a9983969f43df5f75483c8196df1963d89cb97Brian Paul   case GL_ALWAYS:
14429a9983969f43df5f75483c8196df1963d89cb97Brian Paul      Z_TEST(1);
14529a9983969f43df5f75483c8196df1963d89cb97Brian Paul      break;
14629a9983969f43df5f75483c8196df1963d89cb97Brian Paul   case GL_NEVER:
14729a9983969f43df5f75483c8196df1963d89cb97Brian Paul      memset(mask, 0, n * sizeof(GLubyte));
14829a9983969f43df5f75483c8196df1963d89cb97Brian Paul      break;
14929a9983969f43df5f75483c8196df1963d89cb97Brian Paul   default:
15029a9983969f43df5f75483c8196df1963d89cb97Brian Paul      _mesa_problem(ctx, "Bad depth func in depth_test_span32");
151e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
152e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
153e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   return passed;
154e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
155e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
15673856817973caab283427c52152672f524c49a07Brian Paul
15773856817973caab283427c52152672f524c49a07Brian Paul/**
15873856817973caab283427c52152672f524c49a07Brian Paul * Clamp fragment Z values to the depth near/far range (glDepthRange()).
15973856817973caab283427c52152672f524c49a07Brian Paul * This is used when GL_ARB_depth_clamp/GL_DEPTH_CLAMP is turned on.
16073856817973caab283427c52152672f524c49a07Brian Paul * In that case, vertexes are not clipped against the near/far planes
16173856817973caab283427c52152672f524c49a07Brian Paul * so rasterization will produce fragment Z values outside the usual
16273856817973caab283427c52152672f524c49a07Brian Paul * [0,1] range.
16373856817973caab283427c52152672f524c49a07Brian Paul */
164b4922b533155cc139ebafb111502bb55d2ad2ccfEric Anholtvoid
165f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_depth_clamp_span( struct gl_context *ctx, SWspan *span )
166b4922b533155cc139ebafb111502bb55d2ad2ccfEric Anholt{
167b4922b533155cc139ebafb111502bb55d2ad2ccfEric Anholt   struct gl_framebuffer *fb = ctx->DrawBuffer;
168b4922b533155cc139ebafb111502bb55d2ad2ccfEric Anholt   const GLuint count = span->end;
16973856817973caab283427c52152672f524c49a07Brian Paul   GLint *zValues = (GLint *) span->array->z; /* sign change */
17073856817973caab283427c52152672f524c49a07Brian Paul   GLint min, max;
17132ec3f26731ac998b6fda7ce596ec568d6f76eebEric Anholt   GLfloat min_f, max_f;
17273856817973caab283427c52152672f524c49a07Brian Paul   GLuint i;
173b4922b533155cc139ebafb111502bb55d2ad2ccfEric Anholt
17432ec3f26731ac998b6fda7ce596ec568d6f76eebEric Anholt   if (ctx->Viewport.Near < ctx->Viewport.Far) {
17532ec3f26731ac998b6fda7ce596ec568d6f76eebEric Anholt      min_f = ctx->Viewport.Near;
17632ec3f26731ac998b6fda7ce596ec568d6f76eebEric Anholt      max_f = ctx->Viewport.Far;
17732ec3f26731ac998b6fda7ce596ec568d6f76eebEric Anholt   } else {
17832ec3f26731ac998b6fda7ce596ec568d6f76eebEric Anholt      min_f = ctx->Viewport.Far;
17932ec3f26731ac998b6fda7ce596ec568d6f76eebEric Anholt      max_f = ctx->Viewport.Near;
18032ec3f26731ac998b6fda7ce596ec568d6f76eebEric Anholt   }
18132ec3f26731ac998b6fda7ce596ec568d6f76eebEric Anholt
18273856817973caab283427c52152672f524c49a07Brian Paul   /* Convert floating point values in [0,1] to device Z coordinates in
18373856817973caab283427c52152672f524c49a07Brian Paul    * [0, DepthMax].
184fab1f07d6ad01463897ae792f4b33738afb07369Jeff Smith    * ex: If the Z buffer has 24 bits, DepthMax = 0xffffff.
18573856817973caab283427c52152672f524c49a07Brian Paul    *
18673856817973caab283427c52152672f524c49a07Brian Paul    * XXX this all falls apart if we have 31 or more bits of Z because
18773856817973caab283427c52152672f524c49a07Brian Paul    * the triangle rasterization code produces unsigned Z values.  Negative
18873856817973caab283427c52152672f524c49a07Brian Paul    * vertex Z values come out as large fragment Z uints.
18973856817973caab283427c52152672f524c49a07Brian Paul    */
19073856817973caab283427c52152672f524c49a07Brian Paul   min = (GLint) (min_f * fb->_DepthMaxF);
19173856817973caab283427c52152672f524c49a07Brian Paul   max = (GLint) (max_f * fb->_DepthMaxF);
19273856817973caab283427c52152672f524c49a07Brian Paul   if (max < 0)
19373856817973caab283427c52152672f524c49a07Brian Paul      max = 0x7fffffff; /* catch over flow for 30-bit z */
19432ec3f26731ac998b6fda7ce596ec568d6f76eebEric Anholt
19573856817973caab283427c52152672f524c49a07Brian Paul   /* Note that we do the comparisons here using signed integers.
19673856817973caab283427c52152672f524c49a07Brian Paul    */
197b4922b533155cc139ebafb111502bb55d2ad2ccfEric Anholt   for (i = 0; i < count; i++) {
19832ec3f26731ac998b6fda7ce596ec568d6f76eebEric Anholt      if (zValues[i] < min)
19932ec3f26731ac998b6fda7ce596ec568d6f76eebEric Anholt	 zValues[i] = min;
20032ec3f26731ac998b6fda7ce596ec568d6f76eebEric Anholt      if (zValues[i] > max)
20132ec3f26731ac998b6fda7ce596ec568d6f76eebEric Anholt	 zValues[i] = max;
202b4922b533155cc139ebafb111502bb55d2ad2ccfEric Anholt   }
203b4922b533155cc139ebafb111502bb55d2ad2ccfEric Anholt}
204b4922b533155cc139ebafb111502bb55d2ad2ccfEric Anholt
205e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
2068e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul/**
2078e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul * Get array of 32-bit z values from the depth buffer.  With clipping.
208282292f24c0668516db6225114461544b5d38004Brian Paul * Note: the returned values are always in the range [0, 2^32-1].
2098e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul */
2108e7c388b319f5631299cdc43af2f108ce424bb39Brian Paulstatic void
2118e7c388b319f5631299cdc43af2f108ce424bb39Brian Paulget_z32_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
2128e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul               GLuint count, const GLint x[], const GLint y[],
2138e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul               GLuint zbuffer[])
2148e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul{
2150c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul   struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
2168e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul   const GLint w = rb->Width, h = rb->Height;
217e34a54ff451a37a6e6eab529c44330dd6a8b218bBrian Paul   const GLubyte *map = _swrast_pixel_address(rb, 0, 0);
2188e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul   GLuint i;
2198e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul
2208e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul   if (rb->Format == MESA_FORMAT_Z32) {
2210c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul      const GLint rowStride = srb->RowStride;
2228e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul      for (i = 0; i < count; i++) {
2238e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul         if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
2248e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul            zbuffer[i] = *((GLuint *) (map + y[i] * rowStride + x[i] * 4));
2258e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul         }
2268e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul      }
2278e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul   }
2288e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul   else {
22929a9983969f43df5f75483c8196df1963d89cb97Brian Paul      const GLint bpp = _mesa_get_format_bytes(rb->Format);
2300c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul      const GLint rowStride = srb->RowStride;
2318e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul      for (i = 0; i < count; i++) {
2328e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul         if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
2338e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul            const GLubyte *src = map + y[i] * rowStride+ x[i] * bpp;
2348e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul            _mesa_unpack_uint_z_row(rb->Format, 1, src, &zbuffer[i]);
2358e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul         }
2368e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul      }
2378e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul   }
2388e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul}
2398e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul
240282292f24c0668516db6225114461544b5d38004Brian Paul
241282292f24c0668516db6225114461544b5d38004Brian Paul/**
242282292f24c0668516db6225114461544b5d38004Brian Paul * Put an array of 32-bit z values into the depth buffer.
243282292f24c0668516db6225114461544b5d38004Brian Paul * Note: the z values are always in the range [0, 2^32-1].
244282292f24c0668516db6225114461544b5d38004Brian Paul */
24529a9983969f43df5f75483c8196df1963d89cb97Brian Paulstatic void
24629a9983969f43df5f75483c8196df1963d89cb97Brian Paulput_z32_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
24729a9983969f43df5f75483c8196df1963d89cb97Brian Paul               GLuint count, const GLint x[], const GLint y[],
24829a9983969f43df5f75483c8196df1963d89cb97Brian Paul               const GLuint zvalues[], const GLubyte mask[])
24910f30eb43835c57c00783390a02d72daf4f78e26Brian Paul{
2500c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul   struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
25129a9983969f43df5f75483c8196df1963d89cb97Brian Paul   const GLint w = rb->Width, h = rb->Height;
252e34a54ff451a37a6e6eab529c44330dd6a8b218bBrian Paul   GLubyte *map = _swrast_pixel_address(rb, 0, 0);
25329a9983969f43df5f75483c8196df1963d89cb97Brian Paul   GLuint i;
25410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
25529a9983969f43df5f75483c8196df1963d89cb97Brian Paul   if (rb->Format == MESA_FORMAT_Z32) {
256cf386f0a2ba3efcfd6ddbfcbebaf98a9bfa7a29fBrian Paul      const GLint rowStride = srb->RowStride;
25729a9983969f43df5f75483c8196df1963d89cb97Brian Paul      for (i = 0; i < count; i++) {
25829a9983969f43df5f75483c8196df1963d89cb97Brian Paul         if (mask[i] && x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
25929a9983969f43df5f75483c8196df1963d89cb97Brian Paul            GLuint *dst = (GLuint *) (map + y[i] * rowStride + x[i] * 4);
26029a9983969f43df5f75483c8196df1963d89cb97Brian Paul            *dst = zvalues[i];
26129a9983969f43df5f75483c8196df1963d89cb97Brian Paul         }
26210f30eb43835c57c00783390a02d72daf4f78e26Brian Paul      }
263e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
264e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   else {
26529a9983969f43df5f75483c8196df1963d89cb97Brian Paul      gl_pack_uint_z_func packZ = _mesa_get_pack_uint_z_func(rb->Format);
26629a9983969f43df5f75483c8196df1963d89cb97Brian Paul      const GLint bpp = _mesa_get_format_bytes(rb->Format);
2670c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul      const GLint rowStride = srb->RowStride;
26829a9983969f43df5f75483c8196df1963d89cb97Brian Paul      for (i = 0; i < count; i++) {
26929a9983969f43df5f75483c8196df1963d89cb97Brian Paul         if (mask[i] && x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
27029a9983969f43df5f75483c8196df1963d89cb97Brian Paul            void *dst = map + y[i] * rowStride + x[i] * bpp;
27129a9983969f43df5f75483c8196df1963d89cb97Brian Paul            packZ(zvalues + i, dst);
27229a9983969f43df5f75483c8196df1963d89cb97Brian Paul         }
273b7f5e92f1749ce4601a758f66ddc64959f11742bBrian Paul      }
27410f30eb43835c57c00783390a02d72daf4f78e26Brian Paul   }
27510f30eb43835c57c00783390a02d72daf4f78e26Brian Paul}
27610f30eb43835c57c00783390a02d72daf4f78e26Brian Paul
277e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
27829a9983969f43df5f75483c8196df1963d89cb97Brian Paul/**
27929a9983969f43df5f75483c8196df1963d89cb97Brian Paul * Apply depth (Z) buffer testing to the span.
28029a9983969f43df5f75483c8196df1963d89cb97Brian Paul * \return approx number of pixels that passed (only zero is reliable)
281e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
28229a9983969f43df5f75483c8196df1963d89cb97Brian PaulGLuint
28329a9983969f43df5f75483c8196df1963d89cb97Brian Paul_swrast_depth_test_span(struct gl_context *ctx, SWspan *span)
284e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
285e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   struct gl_framebuffer *fb = ctx->DrawBuffer;
28629a9983969f43df5f75483c8196df1963d89cb97Brian Paul   struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
28729a9983969f43df5f75483c8196df1963d89cb97Brian Paul   const GLint bpp = _mesa_get_format_bytes(rb->Format);
288e34a54ff451a37a6e6eab529c44330dd6a8b218bBrian Paul   void *zStart;
289e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   const GLuint count = span->end;
29029a9983969f43df5f75483c8196df1963d89cb97Brian Paul   const GLuint *fragZ = span->array->z;
29177df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul   GLubyte *mask = span->array->mask;
29229a9983969f43df5f75483c8196df1963d89cb97Brian Paul   void *zBufferVals;
29329a9983969f43df5f75483c8196df1963d89cb97Brian Paul   GLuint *zBufferTemp = NULL;
29429a9983969f43df5f75483c8196df1963d89cb97Brian Paul   GLuint passed;
295282292f24c0668516db6225114461544b5d38004Brian Paul   GLuint zBits = _mesa_get_format_bits(rb->Format, GL_DEPTH_BITS);
29629a9983969f43df5f75483c8196df1963d89cb97Brian Paul   GLboolean ztest16 = GL_FALSE;
29779c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul
298e34a54ff451a37a6e6eab529c44330dd6a8b218bBrian Paul   if (span->arrayMask & SPAN_XY)
299e34a54ff451a37a6e6eab529c44330dd6a8b218bBrian Paul      zStart = NULL;
300e34a54ff451a37a6e6eab529c44330dd6a8b218bBrian Paul   else
301e34a54ff451a37a6e6eab529c44330dd6a8b218bBrian Paul      zStart = _swrast_pixel_address(rb, span->x, span->y);
302e34a54ff451a37a6e6eab529c44330dd6a8b218bBrian Paul
30329a9983969f43df5f75483c8196df1963d89cb97Brian Paul   if (rb->Format == MESA_FORMAT_Z16 && !(span->arrayMask & SPAN_XY)) {
30429a9983969f43df5f75483c8196df1963d89cb97Brian Paul      /* directly read/write row of 16-bit Z values */
30529a9983969f43df5f75483c8196df1963d89cb97Brian Paul      zBufferVals = zStart;
30629a9983969f43df5f75483c8196df1963d89cb97Brian Paul      ztest16 = GL_TRUE;
30729a9983969f43df5f75483c8196df1963d89cb97Brian Paul   }
30829a9983969f43df5f75483c8196df1963d89cb97Brian Paul   else if (rb->Format == MESA_FORMAT_Z32 && !(span->arrayMask & SPAN_XY)) {
30929a9983969f43df5f75483c8196df1963d89cb97Brian Paul      /* directly read/write row of 32-bit Z values */
31029a9983969f43df5f75483c8196df1963d89cb97Brian Paul      zBufferVals = zStart;
311e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
312e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
31329a9983969f43df5f75483c8196df1963d89cb97Brian Paul      /* copy Z buffer values into temp buffer (32-bit Z values) */
31429a9983969f43df5f75483c8196df1963d89cb97Brian Paul      zBufferTemp = (GLuint *) malloc(count * sizeof(GLuint));
31529a9983969f43df5f75483c8196df1963d89cb97Brian Paul      if (!zBufferTemp)
31629a9983969f43df5f75483c8196df1963d89cb97Brian Paul         return 0;
31729a9983969f43df5f75483c8196df1963d89cb97Brian Paul
31829a9983969f43df5f75483c8196df1963d89cb97Brian Paul      if (span->arrayMask & SPAN_XY) {
31929a9983969f43df5f75483c8196df1963d89cb97Brian Paul         get_z32_values(ctx, rb, count,
32029a9983969f43df5f75483c8196df1963d89cb97Brian Paul                        span->array->x, span->array->y, zBufferTemp);
321e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
322e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      else {
32329a9983969f43df5f75483c8196df1963d89cb97Brian Paul         _mesa_unpack_uint_z_row(rb->Format, count, zStart, zBufferTemp);
324e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
325e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
326282292f24c0668516db6225114461544b5d38004Brian Paul      if (zBits == 24) {
32729a9983969f43df5f75483c8196df1963d89cb97Brian Paul         GLuint i;
32829a9983969f43df5f75483c8196df1963d89cb97Brian Paul         /* Convert depth buffer values from 32 to 24 bits to match the
32929a9983969f43df5f75483c8196df1963d89cb97Brian Paul          * fragment Z values generated by rasterization.
33029a9983969f43df5f75483c8196df1963d89cb97Brian Paul          */
33129a9983969f43df5f75483c8196df1963d89cb97Brian Paul         for (i = 0; i < count; i++) {
33229a9983969f43df5f75483c8196df1963d89cb97Brian Paul            zBufferTemp[i] >>= 8;
33329a9983969f43df5f75483c8196df1963d89cb97Brian Paul         }
33429a9983969f43df5f75483c8196df1963d89cb97Brian Paul      }
335282292f24c0668516db6225114461544b5d38004Brian Paul      else if (zBits == 16) {
336282292f24c0668516db6225114461544b5d38004Brian Paul         GLuint i;
337282292f24c0668516db6225114461544b5d38004Brian Paul         /* Convert depth buffer values from 32 to 16 bits */
338282292f24c0668516db6225114461544b5d38004Brian Paul         for (i = 0; i < count; i++) {
339282292f24c0668516db6225114461544b5d38004Brian Paul            zBufferTemp[i] >>= 16;
340282292f24c0668516db6225114461544b5d38004Brian Paul         }
341282292f24c0668516db6225114461544b5d38004Brian Paul      }
342282292f24c0668516db6225114461544b5d38004Brian Paul      else {
343282292f24c0668516db6225114461544b5d38004Brian Paul         assert(zBits == 32);
344282292f24c0668516db6225114461544b5d38004Brian Paul      }
345e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
34629a9983969f43df5f75483c8196df1963d89cb97Brian Paul      zBufferVals = zBufferTemp;
34729a9983969f43df5f75483c8196df1963d89cb97Brian Paul   }
348e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
34929a9983969f43df5f75483c8196df1963d89cb97Brian Paul   /* do the depth test either with 16 or 32-bit values */
35029a9983969f43df5f75483c8196df1963d89cb97Brian Paul   if (ztest16)
35129a9983969f43df5f75483c8196df1963d89cb97Brian Paul      passed = depth_test_span16(ctx, count, zBufferVals, fragZ, mask);
35279c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul   else
35329a9983969f43df5f75483c8196df1963d89cb97Brian Paul      passed = depth_test_span32(ctx, count, zBufferVals, fragZ, mask);
35429a9983969f43df5f75483c8196df1963d89cb97Brian Paul
35529a9983969f43df5f75483c8196df1963d89cb97Brian Paul   if (zBufferTemp) {
35629a9983969f43df5f75483c8196df1963d89cb97Brian Paul      /* need to write temp Z values back into the buffer */
35729a9983969f43df5f75483c8196df1963d89cb97Brian Paul
358282292f24c0668516db6225114461544b5d38004Brian Paul      /* Convert depth buffer values back to 32-bit values.  The least
359282292f24c0668516db6225114461544b5d38004Brian Paul       * significant bits don't matter since they'll get dropped when
360282292f24c0668516db6225114461544b5d38004Brian Paul       * they're packed back into the depth buffer.
361282292f24c0668516db6225114461544b5d38004Brian Paul       */
362282292f24c0668516db6225114461544b5d38004Brian Paul      if (zBits == 24) {
36329a9983969f43df5f75483c8196df1963d89cb97Brian Paul         GLuint i;
36429a9983969f43df5f75483c8196df1963d89cb97Brian Paul         for (i = 0; i < count; i++) {
36529a9983969f43df5f75483c8196df1963d89cb97Brian Paul            zBufferTemp[i] = (zBufferTemp[i] << 8);
36629a9983969f43df5f75483c8196df1963d89cb97Brian Paul         }
36729a9983969f43df5f75483c8196df1963d89cb97Brian Paul      }
368282292f24c0668516db6225114461544b5d38004Brian Paul      else if (zBits == 16) {
369282292f24c0668516db6225114461544b5d38004Brian Paul         GLuint i;
370282292f24c0668516db6225114461544b5d38004Brian Paul         for (i = 0; i < count; i++) {
371282292f24c0668516db6225114461544b5d38004Brian Paul            zBufferTemp[i] = zBufferTemp[i] << 16;
372282292f24c0668516db6225114461544b5d38004Brian Paul         }
373282292f24c0668516db6225114461544b5d38004Brian Paul      }
37429a9983969f43df5f75483c8196df1963d89cb97Brian Paul
37529a9983969f43df5f75483c8196df1963d89cb97Brian Paul      if (span->arrayMask & SPAN_XY) {
37629a9983969f43df5f75483c8196df1963d89cb97Brian Paul         /* random locations */
37729a9983969f43df5f75483c8196df1963d89cb97Brian Paul         put_z32_values(ctx, rb, count, span->array->x, span->array->y,
37829a9983969f43df5f75483c8196df1963d89cb97Brian Paul                        zBufferTemp, mask);
37929a9983969f43df5f75483c8196df1963d89cb97Brian Paul      }
38029a9983969f43df5f75483c8196df1963d89cb97Brian Paul      else {
38129a9983969f43df5f75483c8196df1963d89cb97Brian Paul         /* horizontal row */
38229a9983969f43df5f75483c8196df1963d89cb97Brian Paul         gl_pack_uint_z_func packZ = _mesa_get_pack_uint_z_func(rb->Format);
38329a9983969f43df5f75483c8196df1963d89cb97Brian Paul         GLubyte *dst = zStart;
38429a9983969f43df5f75483c8196df1963d89cb97Brian Paul         GLuint i;
38529a9983969f43df5f75483c8196df1963d89cb97Brian Paul         for (i = 0; i < count; i++) {
38629a9983969f43df5f75483c8196df1963d89cb97Brian Paul            if (mask[i]) {
38729a9983969f43df5f75483c8196df1963d89cb97Brian Paul               packZ(&zBufferTemp[i], dst);
38829a9983969f43df5f75483c8196df1963d89cb97Brian Paul            }
38929a9983969f43df5f75483c8196df1963d89cb97Brian Paul            dst += bpp;
39029a9983969f43df5f75483c8196df1963d89cb97Brian Paul         }
39129a9983969f43df5f75483c8196df1963d89cb97Brian Paul      }
39229a9983969f43df5f75483c8196df1963d89cb97Brian Paul
39329a9983969f43df5f75483c8196df1963d89cb97Brian Paul      free(zBufferTemp);
39429a9983969f43df5f75483c8196df1963d89cb97Brian Paul   }
39529a9983969f43df5f75483c8196df1963d89cb97Brian Paul
39629a9983969f43df5f75483c8196df1963d89cb97Brian Paul   if (passed < count) {
39729a9983969f43df5f75483c8196df1963d89cb97Brian Paul      span->writeAll = GL_FALSE;
39829a9983969f43df5f75483c8196df1963d89cb97Brian Paul   }
39929a9983969f43df5f75483c8196df1963d89cb97Brian Paul   return passed;
400733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul}
401733a4b602bbbfda83ee03b7ae4f3737bbe659034Brian Paul
402e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
403e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul/**
404e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul * GL_EXT_depth_bounds_test extension.
405e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul * Discard fragments depending on whether the corresponding Z-buffer
406e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul * values are outside the depth bounds test range.
407e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul * Note: we test the Z buffer values, not the fragment Z values!
408e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul * \return GL_TRUE if any fragments pass, GL_FALSE if no fragments pass
409e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul */
410e5b244ff7f984805c1bcc020342f1300f2639c71Brian PaulGLboolean
411f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_depth_bounds_test( struct gl_context *ctx, SWspan *span )
412e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul{
413e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   struct gl_framebuffer *fb = ctx->DrawBuffer;
41482f28c0a12cf04e4fd3c4cfc4658919943fca825Brian Paul   struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
415e34a54ff451a37a6e6eab529c44330dd6a8b218bBrian Paul   GLubyte *zStart;
416e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   GLuint zMin = (GLuint) (ctx->Depth.BoundsMin * fb->_DepthMaxF + 0.5F);
417e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   GLuint zMax = (GLuint) (ctx->Depth.BoundsMax * fb->_DepthMaxF + 0.5F);
418e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul   GLubyte *mask = span->array->mask;
419e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   const GLuint count = span->end;
420e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul   GLuint i;
421e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul   GLboolean anyPass = GL_FALSE;
422237b2fca7aad9b15f3d8b6928d96cdff790b202aBrian Paul   GLuint *zBufferTemp;
42382f28c0a12cf04e4fd3c4cfc4658919943fca825Brian Paul   const GLuint *zBufferVals;
424e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul
425237b2fca7aad9b15f3d8b6928d96cdff790b202aBrian Paul   zBufferTemp = (GLuint *) malloc(count * sizeof(GLuint));
426237b2fca7aad9b15f3d8b6928d96cdff790b202aBrian Paul   if (!zBufferTemp) {
427237b2fca7aad9b15f3d8b6928d96cdff790b202aBrian Paul      /* don't generate a stream of OUT_OF_MEMORY errors here */
428237b2fca7aad9b15f3d8b6928d96cdff790b202aBrian Paul      return GL_FALSE;
429237b2fca7aad9b15f3d8b6928d96cdff790b202aBrian Paul   }
430237b2fca7aad9b15f3d8b6928d96cdff790b202aBrian Paul
431e34a54ff451a37a6e6eab529c44330dd6a8b218bBrian Paul   if (span->arrayMask & SPAN_XY)
432e34a54ff451a37a6e6eab529c44330dd6a8b218bBrian Paul      zStart = NULL;
433e34a54ff451a37a6e6eab529c44330dd6a8b218bBrian Paul   else
434e34a54ff451a37a6e6eab529c44330dd6a8b218bBrian Paul      zStart = _swrast_pixel_address(rb, span->x, span->y);
435e34a54ff451a37a6e6eab529c44330dd6a8b218bBrian Paul
43682f28c0a12cf04e4fd3c4cfc4658919943fca825Brian Paul   if (rb->Format == MESA_FORMAT_Z32 && !(span->arrayMask & SPAN_XY)) {
43782f28c0a12cf04e4fd3c4cfc4658919943fca825Brian Paul      /* directly access 32-bit values in the depth buffer */
43882f28c0a12cf04e4fd3c4cfc4658919943fca825Brian Paul      zBufferVals = (const GLuint *) zStart;
439e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul   }
440e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul   else {
44182f28c0a12cf04e4fd3c4cfc4658919943fca825Brian Paul      /* unpack Z values into a temporary array */
442e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul      if (span->arrayMask & SPAN_XY) {
4438e7c388b319f5631299cdc43af2f108ce424bb39Brian Paul         get_z32_values(ctx, rb, count, span->array->x, span->array->y,
44482f28c0a12cf04e4fd3c4cfc4658919943fca825Brian Paul                        zBufferTemp);
445e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul      }
446e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul      else {
44782f28c0a12cf04e4fd3c4cfc4658919943fca825Brian Paul         _mesa_unpack_uint_z_row(rb->Format, count, zStart, zBufferTemp);
448e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      }
44982f28c0a12cf04e4fd3c4cfc4658919943fca825Brian Paul      zBufferVals = zBufferTemp;
45082f28c0a12cf04e4fd3c4cfc4658919943fca825Brian Paul   }
451e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
45282f28c0a12cf04e4fd3c4cfc4658919943fca825Brian Paul   /* Now do the tests */
45382f28c0a12cf04e4fd3c4cfc4658919943fca825Brian Paul   for (i = 0; i < count; i++) {
45482f28c0a12cf04e4fd3c4cfc4658919943fca825Brian Paul      if (mask[i]) {
45582f28c0a12cf04e4fd3c4cfc4658919943fca825Brian Paul         if (zBufferVals[i] < zMin || zBufferVals[i] > zMax)
45682f28c0a12cf04e4fd3c4cfc4658919943fca825Brian Paul            mask[i] = GL_FALSE;
45782f28c0a12cf04e4fd3c4cfc4658919943fca825Brian Paul         else
45882f28c0a12cf04e4fd3c4cfc4658919943fca825Brian Paul            anyPass = GL_TRUE;
459e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul      }
460e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul   }
461e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
462237b2fca7aad9b15f3d8b6928d96cdff790b202aBrian Paul   free(zBufferTemp);
463237b2fca7aad9b15f3d8b6928d96cdff790b202aBrian Paul
464e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul   return anyPass;
465e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul}
466e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul
467e5b244ff7f984805c1bcc020342f1300f2639c71Brian Paul
468e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
469e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/**********************************************************************/
470e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*****                      Read Depth Buffer                     *****/
471e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/**********************************************************************/
472e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
473e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
47479c2f534916046fab91f53ebd37f705bd25f7dcbBrian Paul/**
47582e314252f0b706c3ae1c748e9d64d8fa58812dbBrian Paul * Read a span of depth values from the given depth renderbuffer, returning
47682e314252f0b706c3ae1c748e9d64d8fa58812dbBrian Paul * the values as GLfloats.
47782e314252f0b706c3ae1c748e9d64d8fa58812dbBrian Paul * This function does clipping to prevent reading outside the depth buffer's
47877c85f014aa1db44f60b1b3291af8132ab65f444Brian Paul * bounds.
479e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
480e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellvoid
4814d6b0927ab6533f0384f463e2ccfc3eb5f80ecf9Brian Paul_swrast_read_depth_span_float(struct gl_context *ctx,
4824d6b0927ab6533f0384f463e2ccfc3eb5f80ecf9Brian Paul                              struct gl_renderbuffer *rb,
4834d6b0927ab6533f0384f463e2ccfc3eb5f80ecf9Brian Paul                              GLint n, GLint x, GLint y, GLfloat depth[])
484e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
48582e314252f0b706c3ae1c748e9d64d8fa58812dbBrian Paul   if (!rb) {
48682e314252f0b706c3ae1c748e9d64d8fa58812dbBrian Paul      /* really only doing this to prevent FP exceptions later */
4876bf1ea897fa470af58fe8916dff45e2da79634a3Brian Paul      memset(depth, 0, n * sizeof(GLfloat));
48814f21c785087f86d291243400e59ebfc8721c4f6Brian Paul      return;
48982e314252f0b706c3ae1c748e9d64d8fa58812dbBrian Paul   }
49082e314252f0b706c3ae1c748e9d64d8fa58812dbBrian Paul
491e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if (y < 0 || y >= (GLint) rb->Height ||
49282b29819a9ede846ad5c37ff70b71d45cf72357aBrian Paul       x + n <= 0 || x >= (GLint) rb->Width) {
493e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* span is completely outside framebuffer */
4946bf1ea897fa470af58fe8916dff45e2da79634a3Brian Paul      memset(depth, 0, n * sizeof(GLfloat));
495e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      return;
496e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
497e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
498e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (x < 0) {
499e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      GLint dx = -x;
500e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      GLint i;
501e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      for (i = 0; i < dx; i++)
50282e314252f0b706c3ae1c748e9d64d8fa58812dbBrian Paul         depth[i] = 0.0;
503e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      x = 0;
504e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      n -= dx;
505e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      depth += dx;
506e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
507e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if (x + n > (GLint) rb->Width) {
508e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      GLint dx = x + n - (GLint) rb->Width;
509e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      GLint i;
510e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      for (i = 0; i < dx; i++)
51182e314252f0b706c3ae1c748e9d64d8fa58812dbBrian Paul         depth[n - i - 1] = 0.0;
512e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      n -= dx;
513e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
514e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (n <= 0) {
515e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      return;
516e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
517e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
518242fd9df3b2266402b3f6b20447798fb3bf57d53Brian Paul   _mesa_unpack_float_z_row(rb->Format, n, _swrast_pixel_address(rb, x, y),
519242fd9df3b2266402b3f6b20447798fb3bf57d53Brian Paul                            depth);
520e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
521e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
522fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
523a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul/**
524fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul * Clear the given z/depth renderbuffer.  If the buffer is a combined
525fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul * depth+stencil buffer, only the Z bits will be touched.
526e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
527e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellvoid
528fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul_swrast_clear_depth_buffer(struct gl_context *ctx)
529e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
530fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   struct gl_renderbuffer *rb =
531fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
532e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   GLint x, y, width, height;
533fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   GLubyte *map;
534fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   GLint rowStride, i, j;
535fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   GLbitfield mapMode;
536328a039413fd2b8649511f1ca130df2a59f2c71cBrian Paul
537b5e9b0e56231065f6324bbd3c2c35ca53b46ddf8Brian   if (!rb || !ctx->Depth.Mask) {
538e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* no depth buffer, or writing to it is disabled */
539e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      return;
540e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
541e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
542e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   /* compute region to clear */
543e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   x = ctx->DrawBuffer->_Xmin;
544e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   y = ctx->DrawBuffer->_Ymin;
545e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
546e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
547e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
548fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   mapMode = GL_MAP_WRITE_BIT;
549fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   if (rb->Format == MESA_FORMAT_S8_Z24 ||
550fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul       rb->Format == MESA_FORMAT_X8_Z24 ||
551fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul       rb->Format == MESA_FORMAT_Z24_S8 ||
552fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul       rb->Format == MESA_FORMAT_Z24_X8) {
553fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      mapMode |= GL_MAP_READ_BIT;
554fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   }
555fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
556fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
557fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul                               mapMode, &map, &rowStride);
558fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   if (!map) {
559fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(depth)");
560fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      return;
561fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   }
562fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
563fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   switch (rb->Format) {
564fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   case MESA_FORMAT_Z16:
565fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      {
566fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         GLfloat clear = (GLfloat) ctx->Depth.Clear;
567fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         GLushort clearVal = 0;
568fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         _mesa_pack_float_z_row(rb->Format, 1, &clear, &clearVal);
569fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         if (clearVal == 0xffff && width * 2 == rowStride) {
570fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            /* common case */
571fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            memset(map, 0xff, width * height * 2);
572e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         }
573e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         else {
574e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul            for (i = 0; i < height; i++) {
575fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul               GLushort *row = (GLushort *) map;
576e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul               for (j = 0; j < width; j++) {
577fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul                  row[j] = clearVal;
578e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul               }
579fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul               map += rowStride;
580e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            }
581e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
582e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
583fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      break;
584fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   case MESA_FORMAT_Z32:
585fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   case MESA_FORMAT_Z32_FLOAT:
586fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      {
587fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         GLfloat clear = (GLfloat) ctx->Depth.Clear;
588fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         GLuint clearVal = 0;
589fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         _mesa_pack_float_z_row(rb->Format, 1, &clear, &clearVal);
590e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         for (i = 0; i < height; i++) {
591fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            GLuint *row = (GLuint *) map;
592e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul            for (j = 0; j < width; j++) {
593fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul               row[j] = clearVal;
594e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell            }
595fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            map += rowStride;
596e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
597e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
598fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      break;
599fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   case MESA_FORMAT_S8_Z24:
600fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   case MESA_FORMAT_X8_Z24:
601fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   case MESA_FORMAT_Z24_S8:
602fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   case MESA_FORMAT_Z24_X8:
603fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      {
604fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         GLfloat clear = (GLfloat) ctx->Depth.Clear;
605fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         GLuint clearVal = 0;
606fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         GLuint mask;
607fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
608fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         if (rb->Format == MESA_FORMAT_S8_Z24 ||
609fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul             rb->Format == MESA_FORMAT_X8_Z24)
610fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            mask = 0xff000000;
611fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         else
612fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            mask = 0xff;
613fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
614fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         _mesa_pack_float_z_row(rb->Format, 1, &clear, &clearVal);
615e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         for (i = 0; i < height; i++) {
616fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            GLuint *row = (GLuint *) map;
617fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            for (j = 0; j < width; j++) {
618fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul               row[j] = (row[j] & mask) | clearVal;
619fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            }
620fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            map += rowStride;
621e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
622fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
623e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
624fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      break;
625fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   case MESA_FORMAT_Z32_FLOAT_X24S8:
626fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      /* XXX untested */
627fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      {
628fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         GLfloat clearVal = (GLfloat) ctx->Depth.Clear;
629e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         for (i = 0; i < height; i++) {
630fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            GLfloat *row = (GLfloat *) map;
631fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            for (j = 0; j < width; j++) {
632fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul               row[j * 2] = clearVal;
633fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            }
634fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            map += rowStride;
635e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         }
636e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
637fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      break;
638fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   default:
639fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      _mesa_problem(ctx, "Unexpected depth buffer format %s"
640fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul                    " in _swrast_clear_depth_buffer()",
641fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul                    _mesa_get_format_name(rb->Format));
642fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   }
643fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
644fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   ctx->Driver.UnmapRenderbuffer(ctx, rb);
645fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul}
646fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
647fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
648fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
649fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
650fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul/**
651fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul * Clear both depth and stencil values in a combined depth+stencil buffer.
652fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul */
653fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paulvoid
654fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul_swrast_clear_depth_stencil_buffer(struct gl_context *ctx)
655fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul{
656fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   const GLubyte stencilBits = ctx->DrawBuffer->Visual.stencilBits;
657fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   const GLuint writeMask = ctx->Stencil.WriteMask[0];
658fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   const GLuint stencilMax = (1 << stencilBits) - 1;
659fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   struct gl_renderbuffer *rb =
660fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
661fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   GLint x, y, width, height;
662fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   GLbitfield mapMode;
663fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   GLubyte *map;
664fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   GLint rowStride, i, j;
665fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
666fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   /* check that we really have a combined depth+stencil buffer */
667fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   assert(rb == ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer);
668fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
669fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   /* compute region to clear */
670fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   x = ctx->DrawBuffer->_Xmin;
671fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   y = ctx->DrawBuffer->_Ymin;
672fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
673fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
674fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
675fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   mapMode = GL_MAP_WRITE_BIT;
676fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   if ((writeMask & stencilMax) != stencilMax) {
677fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      /* need to mask stencil values */
678fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      mapMode |= GL_MAP_READ_BIT;
679fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   }
680fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
681fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
682fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul                               mapMode, &map, &rowStride);
683fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   if (!map) {
684fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(depth+stencil)");
685fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      return;
686fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   }
687fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
688fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   switch (rb->Format) {
689fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   case MESA_FORMAT_S8_Z24:
690fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   case MESA_FORMAT_Z24_S8:
691fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      {
692fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         GLfloat zClear = (GLfloat) ctx->Depth.Clear;
693fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         GLuint clear = 0, mask;
694fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
695fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         _mesa_pack_float_z_row(rb->Format, 1, &zClear, &clear);
696fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
697fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         if (rb->Format == MESA_FORMAT_S8_Z24) {
698fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            mask = ((~writeMask) & 0xff) << 24;
699fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            clear |= (ctx->Stencil.Clear & writeMask & 0xff) << 24;
700fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         }
701fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         else {
702fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            mask = ((~writeMask) & 0xff);
703fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            clear |= (ctx->Stencil.Clear & writeMask & 0xff);
704fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         }
705fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
706fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         for (i = 0; i < height; i++) {
707fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            GLuint *row = (GLuint *) map;
708fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            if (mask != 0x0) {
709fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul               for (j = 0; j < width; j++) {
710fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul                  row[j] = (row[j] & mask) | clear;
711fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul               }
712fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            }
713fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            else {
714fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul               for (j = 0; j < width; j++) {
715fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul                  row[j] = clear;
716fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul               }
717fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            }
718fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            map += rowStride;
719fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         }
720fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      }
721fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      break;
722fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   case MESA_FORMAT_Z32_FLOAT_X24S8:
723fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      /* XXX untested */
724fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      {
725fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         const GLfloat zClear = (GLfloat) ctx->Depth.Clear;
726fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         const GLuint sClear = ctx->Stencil.Clear & writeMask;
727fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         const GLuint sMask = (~writeMask) & 0xff;
728fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         for (i = 0; i < height; i++) {
729fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            GLfloat *zRow = (GLfloat *) map;
730fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            GLuint *sRow = (GLuint *) map;
731fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            for (j = 0; j < width; j++) {
732fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul               zRow[j * 2 + 0] = zClear;
733fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            }
734fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            if (sMask != 0) {
735fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul               for (j = 0; j < width; j++) {
736fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul                  sRow[j * 2 + 1] = (sRow[j * 2 + 1] & sMask) | sClear;
737fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul               }
738fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            }
739fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            else {
740fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul               for (j = 0; j < width; j++) {
741fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul                  sRow[j * 2 + 1] = sClear;
742fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul               }
743fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            }
744fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul            map += rowStride;
745fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul         }
746f39569f5509f9298cb5374b9758296d9149add9bBrian Paul      }
747fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      break;
748fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   default:
749fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul      _mesa_problem(ctx, "Unexpected depth buffer format %s"
750fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul                    " in _swrast_clear_depth_buffer()",
751fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul                    _mesa_get_format_name(rb->Format));
752e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
753fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
754fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul   ctx->Driver.UnmapRenderbuffer(ctx, rb);
755fd104a84591ae854c5d6adc81e2dc31ef6ab9e8aBrian Paul
756e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
757