xref: /reactos/dll/opengl/mesa/depth.c (revision 5f2bebf7)
1 /* $Id: depth.c,v 1.11 1997/07/24 01:24:45 brianp Exp $ */
2 
3 /*
4  * Mesa 3-D graphics library
5  * Version:  2.4
6  * Copyright (C) 1995-1997  Brian Paul
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 
23 
24 /*
25  * $Log: depth.c,v $
26  * Revision 1.11  1997/07/24 01:24:45  brianp
27  * changed precompiled header symbol from PCH to PC_HEADER
28  *
29  * Revision 1.10  1997/05/28 03:24:22  brianp
30  * added precompiled header (PCH) support
31  *
32  * Revision 1.9  1997/04/20 19:54:15  brianp
33  * replaced abort() with gl_problem()
34  *
35  * Revision 1.8  1997/02/27 19:58:52  brianp
36  * don't try to clear depth buffer if there isn't one
37  *
38  * Revision 1.7  1997/01/31 23:33:08  brianp
39  * replaced calloc with malloc in gl_alloc_depth_buffer()
40  *
41  * Revision 1.6  1996/11/04 01:42:07  brianp
42  * multiply Viewport.Sz and .Tz by DEPTH_SCALE
43  *
44  * Revision 1.5  1996/10/09 03:07:25  brianp
45  * replaced malloc with calloc in gl_alloc_depth_buffer()
46  *
47  * Revision 1.4  1996/09/27 01:24:58  brianp
48  * added missing default cases to switches
49  *
50  * Revision 1.3  1996/09/19 00:54:05  brianp
51  * added missing returns after some gl_error() calls
52  *
53  * Revision 1.2  1996/09/15 14:19:16  brianp
54  * now use GLframebuffer and GLvisual
55  *
56  * Revision 1.1  1996/09/13 01:38:16  brianp
57  * Initial revision
58  *
59  */
60 
61 
62 /*
63  * Depth buffer functions
64  */
65 
66 
67 #ifdef PC_HEADER
68 #include "all.h"
69 #else
70 #include <stdlib.h>
71 #include <string.h>
72 #include "context.h"
73 #include "depth.h"
74 #include "dlist.h"
75 #include "macros.h"
76 #include "types.h"
77 #endif
78 
79 
80 
81 /**********************************************************************/
82 /*****                          API Functions                     *****/
83 /**********************************************************************/
84 
85 
86 
gl_ClearDepth(GLcontext * ctx,GLclampd depth)87 void gl_ClearDepth( GLcontext* ctx, GLclampd depth )
88 {
89    if (INSIDE_BEGIN_END(ctx)) {
90       gl_error( ctx, GL_INVALID_OPERATION, "glClearDepth" );
91       return;
92    }
93    ctx->Depth.Clear = (GLfloat) CLAMP( depth, 0.0, 1.0 );
94 }
95 
96 
97 
gl_DepthFunc(GLcontext * ctx,GLenum func)98 void gl_DepthFunc( GLcontext* ctx, GLenum func )
99 {
100    if (INSIDE_BEGIN_END(ctx)) {
101       gl_error( ctx, GL_INVALID_OPERATION, "glDepthFunc" );
102       return;
103    }
104 
105    switch (func) {
106       case GL_NEVER:
107       case GL_LESS:    /* (default) pass if incoming z < stored z */
108       case GL_GEQUAL:
109       case GL_LEQUAL:
110       case GL_GREATER:
111       case GL_NOTEQUAL:
112       case GL_EQUAL:
113       case GL_ALWAYS:
114          ctx->Depth.Func = func;
115          ctx->NewState |= NEW_RASTER_OPS;
116          break;
117       default:
118          gl_error( ctx, GL_INVALID_ENUM, "glDepth.Func" );
119    }
120 }
121 
122 
123 
gl_DepthMask(GLcontext * ctx,GLboolean flag)124 void gl_DepthMask( GLcontext* ctx, GLboolean flag )
125 {
126    if (INSIDE_BEGIN_END(ctx)) {
127       gl_error( ctx, GL_INVALID_OPERATION, "glDepthMask" );
128       return;
129    }
130 
131    /*
132     * GL_TRUE indicates depth buffer writing is enabled (default)
133     * GL_FALSE indicates depth buffer writing is disabled
134     */
135    ctx->Depth.Mask = flag;
136    ctx->NewState |= NEW_RASTER_OPS;
137 }
138 
139 
140 
gl_DepthRange(GLcontext * ctx,GLclampd nearval,GLclampd farval)141 void gl_DepthRange( GLcontext* ctx, GLclampd nearval, GLclampd farval )
142 {
143    /*
144     * nearval - specifies mapping of the near clipping plane to window
145     *   coordinates, default is 0
146     * farval - specifies mapping of the far clipping plane to window
147     *   coordinates, default is 1
148     *
149     * After clipping and div by w, z coords are in -1.0 to 1.0,
150     * corresponding to near and far clipping planes.  glDepthRange
151     * specifies a linear mapping of the normalized z coords in
152     * this range to window z coords.
153     */
154 
155    GLfloat n, f;
156 
157    if (INSIDE_BEGIN_END(ctx)) {
158       gl_error( ctx, GL_INVALID_OPERATION, "glDepthRange" );
159       return;
160    }
161 
162    n = (GLfloat) CLAMP( nearval, 0.0, 1.0 );
163    f = (GLfloat) CLAMP( farval, 0.0, 1.0 );
164 
165    ctx->Viewport.Near = n;
166    ctx->Viewport.Far = f;
167    ctx->Viewport.Sz = DEPTH_SCALE * ((f - n) / 2.0);
168    ctx->Viewport.Tz = DEPTH_SCALE * ((f - n) / 2.0 + n);
169 }
170 
171 
172 
173 /**********************************************************************/
174 /*****                   Depth Testing Functions                  *****/
175 /**********************************************************************/
176 
177 
178 /*
179  * Depth test horizontal spans of fragments.  These functions are called
180  * via ctx->Driver.depth_test_span only.
181  *
182  * Input:  n - number of pixels in the span
183  *         x, y - location of leftmost pixel in span in window coords
184  *         z - array [n] of integer depth values
185  * In/Out:  mask - array [n] of flags (1=draw pixel, 0=don't draw)
186  * Return:  number of pixels which passed depth test
187  */
188 
189 
190 /*
191  * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
192  */
gl_depth_test_span_generic(GLcontext * ctx,GLuint n,GLint x,GLint y,const GLdepth z[],GLubyte mask[])193 GLuint gl_depth_test_span_generic( GLcontext* ctx,
194                                    GLuint n, GLint x, GLint y,
195                                    const GLdepth z[],
196                                    GLubyte mask[] )
197 {
198    GLdepth *zptr = Z_ADDRESS( ctx, x, y );
199    GLubyte *m = mask;
200    GLuint i;
201    GLuint passed = 0;
202 
203    /* switch cases ordered from most frequent to less frequent */
204    switch (ctx->Depth.Func) {
205       case GL_LESS:
206          if (ctx->Depth.Mask) {
207 	    /* Update Z buffer */
208 	    for (i=0; i<n; i++,zptr++,m++) {
209 	       if (*m) {
210 		  if (z[i] < *zptr) {
211 		     /* pass */
212 		     *zptr = z[i];
213 		     passed++;
214 		  }
215 		  else {
216 		     /* fail */
217 		     *m = 0;
218 		  }
219 	       }
220 	    }
221 	 }
222 	 else {
223 	    /* Don't update Z buffer */
224 	    for (i=0; i<n; i++,zptr++,m++) {
225 	       if (*m) {
226 		  if (z[i] < *zptr) {
227 		     /* pass */
228 		     passed++;
229 		  }
230 		  else {
231 		     *m = 0;
232 		  }
233 	       }
234 	    }
235 	 }
236 	 break;
237       case GL_LEQUAL:
238 	 if (ctx->Depth.Mask) {
239 	    /* Update Z buffer */
240 	    for (i=0;i<n;i++,zptr++,m++) {
241 	       if (*m) {
242 		  if (z[i] <= *zptr) {
243 		     *zptr = z[i];
244 		     passed++;
245 		  }
246 		  else {
247 		     *m = 0;
248 		  }
249 	       }
250 	    }
251 	 }
252 	 else {
253 	    /* Don't update Z buffer */
254 	    for (i=0;i<n;i++,zptr++,m++) {
255 	       if (*m) {
256 		  if (z[i] <= *zptr) {
257 		     /* pass */
258 		     passed++;
259 		  }
260 		  else {
261 		     *m = 0;
262 		  }
263 	       }
264 	    }
265 	 }
266 	 break;
267       case GL_GEQUAL:
268 	 if (ctx->Depth.Mask) {
269 	    /* Update Z buffer */
270 	    for (i=0;i<n;i++,zptr++,m++) {
271 	       if (*m) {
272 		  if (z[i] >= *zptr) {
273 		     *zptr = z[i];
274 		     passed++;
275 		  }
276 		  else {
277 		     *m = 0;
278 		  }
279 	       }
280 	    }
281 	 }
282 	 else {
283 	    /* Don't update Z buffer */
284 	    for (i=0;i<n;i++,zptr++,m++) {
285 	       if (*m) {
286 		  if (z[i] >= *zptr) {
287 		     /* pass */
288 		     passed++;
289 		  }
290 		  else {
291 		     *m = 0;
292 		  }
293 	       }
294 	    }
295 	 }
296 	 break;
297       case GL_GREATER:
298 	 if (ctx->Depth.Mask) {
299 	    /* Update Z buffer */
300 	    for (i=0;i<n;i++,zptr++,m++) {
301 	       if (*m) {
302 		  if (z[i] > *zptr) {
303 		     *zptr = z[i];
304 		     passed++;
305 		  }
306 		  else {
307 		     *m = 0;
308 		  }
309 	       }
310 	    }
311 	 }
312 	 else {
313 	    /* Don't update Z buffer */
314 	    for (i=0;i<n;i++,zptr++,m++) {
315 	       if (*m) {
316 		  if (z[i] > *zptr) {
317 		     /* pass */
318 		     passed++;
319 		  }
320 		  else {
321 		     *m = 0;
322 		  }
323 	       }
324 	    }
325 	 }
326 	 break;
327       case GL_NOTEQUAL:
328 	 if (ctx->Depth.Mask) {
329 	    /* Update Z buffer */
330 	    for (i=0;i<n;i++,zptr++,m++) {
331 	       if (*m) {
332 		  if (z[i] != *zptr) {
333 		     *zptr = z[i];
334 		     passed++;
335 		  }
336 		  else {
337 		     *m = 0;
338 		  }
339 	       }
340 	    }
341 	 }
342 	 else {
343 	    /* Don't update Z buffer */
344 	    for (i=0;i<n;i++,zptr++,m++) {
345 	       if (*m) {
346 		  if (z[i] != *zptr) {
347 		     /* pass */
348 		     passed++;
349 		  }
350 		  else {
351 		     *m = 0;
352 		  }
353 	       }
354 	    }
355 	 }
356 	 break;
357       case GL_EQUAL:
358 	 if (ctx->Depth.Mask) {
359 	    /* Update Z buffer */
360 	    for (i=0;i<n;i++,zptr++,m++) {
361 	       if (*m) {
362 		  if (z[i] == *zptr) {
363 		     *zptr = z[i];
364 		     passed++;
365 		  }
366 		  else {
367 		     *m =0;
368 		  }
369 	       }
370 	    }
371 	 }
372 	 else {
373 	    /* Don't update Z buffer */
374 	    for (i=0;i<n;i++,zptr++,m++) {
375 	       if (*m) {
376 		  if (z[i] == *zptr) {
377 		     /* pass */
378 		     passed++;
379 		  }
380 		  else {
381 		     *m =0;
382 		  }
383 	       }
384 	    }
385 	 }
386 	 break;
387       case GL_ALWAYS:
388 	 if (ctx->Depth.Mask) {
389 	    /* Update Z buffer */
390 	    for (i=0;i<n;i++,zptr++,m++) {
391 	       if (*m) {
392 		  *zptr = z[i];
393 		  passed++;
394 	       }
395 	    }
396 	 }
397 	 else {
398 	    /* Don't update Z buffer or mask */
399 	    passed = n;
400 	 }
401 	 break;
402       case GL_NEVER:
403 	 for (i=0;i<n;i++) {
404 	    mask[i] = 0;
405 	 }
406 	 break;
407       default:
408          gl_problem(ctx, "Bad depth func in gl_depth_test_span_generic");
409    } /*switch*/
410 
411    return passed;
412 }
413 
414 
415 
416 /*
417  * glDepthFunc(GL_LESS) and glDepthMask(GL_TRUE).
418  */
gl_depth_test_span_less(GLcontext * ctx,GLuint n,GLint x,GLint y,const GLdepth z[],GLubyte mask[])419 GLuint gl_depth_test_span_less( GLcontext* ctx,
420                                 GLuint n, GLint x, GLint y, const GLdepth z[],
421                                 GLubyte mask[] )
422 {
423    GLdepth *zptr = Z_ADDRESS( ctx, x, y );
424    GLuint i;
425    GLuint passed = 0;
426 
427    for (i=0; i<n; i++) {
428       if (mask[i]) {
429          if (z[i] < zptr[i]) {
430             /* pass */
431             zptr[i] = z[i];
432             passed++;
433          }
434          else {
435             /* fail */
436             mask[i] = 0;
437          }
438       }
439    }
440    return passed;
441 }
442 
443 
444 /*
445  * glDepthFunc(GL_GREATER) and glDepthMask(GL_TRUE).
446  */
gl_depth_test_span_greater(GLcontext * ctx,GLuint n,GLint x,GLint y,const GLdepth z[],GLubyte mask[])447 GLuint gl_depth_test_span_greater( GLcontext* ctx,
448                                    GLuint n, GLint x, GLint y,
449                                    const GLdepth z[],
450                                    GLubyte mask[] )
451 {
452    GLdepth *zptr = Z_ADDRESS( ctx, x, y );
453    GLuint i;
454    GLuint passed = 0;
455 
456    for (i=0; i<n; i++) {
457       if (mask[i]) {
458          if (z[i] > zptr[i]) {
459             /* pass */
460             zptr[i] = z[i];
461             passed++;
462          }
463          else {
464             /* fail */
465             mask[i] = 0;
466          }
467       }
468    }
469    return passed;
470 }
471 
472 
473 
474 /*
475  * Depth test an array of randomly positioned fragments.
476  */
477 
478 
479 #define ZADDR_SETUP   GLdepth *depthbuffer = ctx->Buffer->Depth; \
480                       GLint width = ctx->Buffer->Width;
481 
482 #define ZADDR( X, Y )   (depthbuffer + (Y) * width + (X) )
483 
484 
485 
486 /*
487  * glDepthFunc( any ) and glDepthMask( GL_TRUE or GL_FALSE ).
488  */
gl_depth_test_pixels_generic(GLcontext * ctx,GLuint n,const GLint x[],const GLint y[],const GLdepth z[],GLubyte mask[])489 void gl_depth_test_pixels_generic( GLcontext* ctx,
490                                    GLuint n, const GLint x[], const GLint y[],
491                                    const GLdepth z[], GLubyte mask[] )
492 {
493    register GLdepth *zptr;
494    register GLuint i;
495 
496    /* switch cases ordered from most frequent to less frequent */
497    switch (ctx->Depth.Func) {
498       case GL_LESS:
499          if (ctx->Depth.Mask) {
500 	    /* Update Z buffer */
501 	    for (i=0; i<n; i++) {
502 	       if (mask[i]) {
503 		  zptr = Z_ADDRESS(ctx,x[i],y[i]);
504 		  if (z[i] < *zptr) {
505 		     /* pass */
506 		     *zptr = z[i];
507 		  }
508 		  else {
509 		     /* fail */
510 		     mask[i] = 0;
511 		  }
512 	       }
513 	    }
514 	 }
515 	 else {
516 	    /* Don't update Z buffer */
517 	    for (i=0; i<n; i++) {
518 	       if (mask[i]) {
519 		  zptr = Z_ADDRESS(ctx,x[i],y[i]);
520 		  if (z[i] < *zptr) {
521 		     /* pass */
522 		  }
523 		  else {
524 		     /* fail */
525 		     mask[i] = 0;
526 		  }
527 	       }
528 	    }
529 	 }
530 	 break;
531       case GL_LEQUAL:
532          if (ctx->Depth.Mask) {
533 	    /* Update Z buffer */
534 	    for (i=0; i<n; i++) {
535 	       if (mask[i]) {
536 		  zptr = Z_ADDRESS(ctx,x[i],y[i]);
537 		  if (z[i] <= *zptr) {
538 		     /* pass */
539 		     *zptr = z[i];
540 		  }
541 		  else {
542 		     /* fail */
543 		     mask[i] = 0;
544 		  }
545 	       }
546 	    }
547 	 }
548 	 else {
549 	    /* Don't update Z buffer */
550 	    for (i=0; i<n; i++) {
551 	       if (mask[i]) {
552 		  zptr = Z_ADDRESS(ctx,x[i],y[i]);
553 		  if (z[i] <= *zptr) {
554 		     /* pass */
555 		  }
556 		  else {
557 		     /* fail */
558 		     mask[i] = 0;
559 		  }
560 	       }
561 	    }
562 	 }
563 	 break;
564       case GL_GEQUAL:
565          if (ctx->Depth.Mask) {
566 	    /* Update Z buffer */
567 	    for (i=0; i<n; i++) {
568 	       if (mask[i]) {
569 		  zptr = Z_ADDRESS(ctx,x[i],y[i]);
570 		  if (z[i] >= *zptr) {
571 		     /* pass */
572 		     *zptr = z[i];
573 		  }
574 		  else {
575 		     /* fail */
576 		     mask[i] = 0;
577 		  }
578 	       }
579 	    }
580 	 }
581 	 else {
582 	    /* Don't update Z buffer */
583 	    for (i=0; i<n; i++) {
584 	       if (mask[i]) {
585 		  zptr = Z_ADDRESS(ctx,x[i],y[i]);
586 		  if (z[i] >= *zptr) {
587 		     /* pass */
588 		  }
589 		  else {
590 		     /* fail */
591 		     mask[i] = 0;
592 		  }
593 	       }
594 	    }
595 	 }
596 	 break;
597       case GL_GREATER:
598          if (ctx->Depth.Mask) {
599 	    /* Update Z buffer */
600 	    for (i=0; i<n; i++) {
601 	       if (mask[i]) {
602 		  zptr = Z_ADDRESS(ctx,x[i],y[i]);
603 		  if (z[i] > *zptr) {
604 		     /* pass */
605 		     *zptr = z[i];
606 		  }
607 		  else {
608 		     /* fail */
609 		     mask[i] = 0;
610 		  }
611 	       }
612 	    }
613 	 }
614 	 else {
615 	    /* Don't update Z buffer */
616 	    for (i=0; i<n; i++) {
617 	       if (mask[i]) {
618 		  zptr = Z_ADDRESS(ctx,x[i],y[i]);
619 		  if (z[i] > *zptr) {
620 		     /* pass */
621 		  }
622 		  else {
623 		     /* fail */
624 		     mask[i] = 0;
625 		  }
626 	       }
627 	    }
628 	 }
629 	 break;
630       case GL_NOTEQUAL:
631          if (ctx->Depth.Mask) {
632 	    /* Update Z buffer */
633 	    for (i=0; i<n; i++) {
634 	       if (mask[i]) {
635 		  zptr = Z_ADDRESS(ctx,x[i],y[i]);
636 		  if (z[i] != *zptr) {
637 		     /* pass */
638 		     *zptr = z[i];
639 		  }
640 		  else {
641 		     /* fail */
642 		     mask[i] = 0;
643 		  }
644 	       }
645 	    }
646 	 }
647 	 else {
648 	    /* Don't update Z buffer */
649 	    for (i=0; i<n; i++) {
650 	       if (mask[i]) {
651 		  zptr = Z_ADDRESS(ctx,x[i],y[i]);
652 		  if (z[i] != *zptr) {
653 		     /* pass */
654 		  }
655 		  else {
656 		     /* fail */
657 		     mask[i] = 0;
658 		  }
659 	       }
660 	    }
661 	 }
662 	 break;
663       case GL_EQUAL:
664          if (ctx->Depth.Mask) {
665 	    /* Update Z buffer */
666 	    for (i=0; i<n; i++) {
667 	       if (mask[i]) {
668 		  zptr = Z_ADDRESS(ctx,x[i],y[i]);
669 		  if (z[i] == *zptr) {
670 		     /* pass */
671 		     *zptr = z[i];
672 		  }
673 		  else {
674 		     /* fail */
675 		     mask[i] = 0;
676 		  }
677 	       }
678 	    }
679 	 }
680 	 else {
681 	    /* Don't update Z buffer */
682 	    for (i=0; i<n; i++) {
683 	       if (mask[i]) {
684 		  zptr = Z_ADDRESS(ctx,x[i],y[i]);
685 		  if (z[i] == *zptr) {
686 		     /* pass */
687 		  }
688 		  else {
689 		     /* fail */
690 		     mask[i] = 0;
691 		  }
692 	       }
693 	    }
694 	 }
695 	 break;
696       case GL_ALWAYS:
697 	 if (ctx->Depth.Mask) {
698 	    /* Update Z buffer */
699 	    for (i=0; i<n; i++) {
700 	       if (mask[i]) {
701 		  zptr = Z_ADDRESS(ctx,x[i],y[i]);
702 		  *zptr = z[i];
703 	       }
704 	    }
705 	 }
706 	 else {
707 	    /* Don't update Z buffer or mask */
708 	 }
709 	 break;
710       case GL_NEVER:
711 	 /* depth test never passes */
712 	 for (i=0;i<n;i++) {
713 	    mask[i] = 0;
714 	 }
715 	 break;
716       default:
717          gl_problem(ctx, "Bad depth func in gl_depth_test_pixels_generic");
718    } /*switch*/
719 }
720 
721 
722 
723 /*
724  * glDepthFunc( GL_LESS ) and glDepthMask( GL_TRUE ).
725  */
gl_depth_test_pixels_less(GLcontext * ctx,GLuint n,const GLint x[],const GLint y[],const GLdepth z[],GLubyte mask[])726 void gl_depth_test_pixels_less( GLcontext* ctx,
727                                 GLuint n, const GLint x[], const GLint y[],
728                                 const GLdepth z[], GLubyte mask[] )
729 {
730    GLdepth *zptr;
731    GLuint i;
732 
733    for (i=0; i<n; i++) {
734       if (mask[i]) {
735          zptr = Z_ADDRESS(ctx,x[i],y[i]);
736          if (z[i] < *zptr) {
737             /* pass */
738             *zptr = z[i];
739          }
740          else {
741             /* fail */
742             mask[i] = 0;
743          }
744       }
745    }
746 }
747 
748 
749 /*
750  * glDepthFunc( GL_GREATER ) and glDepthMask( GL_TRUE ).
751  */
gl_depth_test_pixels_greater(GLcontext * ctx,GLuint n,const GLint x[],const GLint y[],const GLdepth z[],GLubyte mask[])752 void gl_depth_test_pixels_greater( GLcontext* ctx,
753                                    GLuint n, const GLint x[], const GLint y[],
754                                    const GLdepth z[], GLubyte mask[] )
755 {
756    GLdepth *zptr;
757    GLuint i;
758 
759    for (i=0; i<n; i++) {
760       if (mask[i]) {
761          zptr = Z_ADDRESS(ctx,x[i],y[i]);
762          if (z[i] > *zptr) {
763             /* pass */
764             *zptr = z[i];
765          }
766          else {
767             /* fail */
768             mask[i] = 0;
769          }
770       }
771    }
772 }
773 
774 
775 
776 
777 /**********************************************************************/
778 /*****                      Read Depth Buffer                     *****/
779 /**********************************************************************/
780 
781 
782 /*
783  * Return a span of depth values from the depth buffer as floats in [0,1].
784  * This function is only called through Driver.read_depth_span_float()
785  * Input:  n - how many pixels
786  *         x,y - location of first pixel
787  * Output:  depth - the array of depth values
788  */
gl_read_depth_span_float(GLcontext * ctx,GLuint n,GLint x,GLint y,GLfloat depth[])789 void gl_read_depth_span_float( GLcontext* ctx,
790                                GLuint n, GLint x, GLint y, GLfloat depth[] )
791 {
792    GLdepth *zptr;
793    GLfloat scale;
794    GLuint i;
795 
796    scale = 1.0F / DEPTH_SCALE;
797 
798    if (ctx->Buffer->Depth) {
799       zptr = Z_ADDRESS( ctx, x, y );
800       for (i=0;i<n;i++) {
801 	 depth[i] = (GLfloat) zptr[i] * scale;
802       }
803    }
804    else {
805       for (i=0;i<n;i++) {
806 	 depth[i] = 0.0F;
807       }
808    }
809 }
810 
811 
812 /*
813  * Return a span of depth values from the depth buffer as integers in
814  * [0,MAX_DEPTH].
815  * This function is only called through Driver.read_depth_span_int()
816  * Input:  n - how many pixels
817  *         x,y - location of first pixel
818  * Output:  depth - the array of depth values
819  */
gl_read_depth_span_int(GLcontext * ctx,GLuint n,GLint x,GLint y,GLdepth depth[])820 void gl_read_depth_span_int( GLcontext* ctx,
821                              GLuint n, GLint x, GLint y, GLdepth depth[] )
822 {
823    if (ctx->Buffer->Depth) {
824       GLdepth *zptr = Z_ADDRESS( ctx, x, y );
825       MEMCPY( depth, zptr, n * sizeof(GLdepth) );
826    }
827    else {
828       GLuint i;
829       for (i=0;i<n;i++) {
830 	 depth[i] = 0.0;
831       }
832    }
833 }
834 
835 
836 
837 /**********************************************************************/
838 /*****                Allocate and Clear Depth Buffer             *****/
839 /**********************************************************************/
840 
841 
842 
843 /*
844  * Allocate a new depth buffer.  If there's already a depth buffer allocated
845  * it will be free()'d.  The new depth buffer will be uniniitalized.
846  * This function is only called through Driver.alloc_depth_buffer.
847  */
gl_alloc_depth_buffer(GLcontext * ctx)848 void gl_alloc_depth_buffer( GLcontext* ctx )
849 {
850    /* deallocate current depth buffer if present */
851    if (ctx->Buffer->Depth) {
852       free(ctx->Buffer->Depth);
853       ctx->Buffer->Depth = NULL;
854    }
855 
856    /* allocate new depth buffer, but don't initialize it */
857    ctx->Buffer->Depth = (GLdepth *) malloc( ctx->Buffer->Width
858                                             * ctx->Buffer->Height
859                                             * sizeof(GLdepth) );
860    if (!ctx->Buffer->Depth) {
861       /* out of memory */
862       ctx->Depth.Test = GL_FALSE;
863       gl_error( ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer" );
864    }
865 }
866 
867 
868 
869 
870 /*
871  * Clear the depth buffer.  If the depth buffer doesn't exist yet we'll
872  * allocate it now.
873  * This function is only called through Driver.clear_depth_buffer.
874  */
gl_clear_depth_buffer(GLcontext * ctx)875 void gl_clear_depth_buffer( GLcontext* ctx )
876 {
877    GLdepth clear_value = (GLdepth) (ctx->Depth.Clear * DEPTH_SCALE);
878 
879    if (ctx->Visual->DepthBits==0 || !ctx->Buffer->Depth) {
880       /* no depth buffer */
881       return;
882    }
883 
884    /* The loops in this function have been written so the IRIX 5.3
885     * C compiler can unroll them.  Hopefully other compilers can too!
886     */
887 
888    if (ctx->Scissor.Enabled) {
889       /* only clear scissor region */
890       GLint y;
891       for (y=ctx->Buffer->Ymin; y<=ctx->Buffer->Ymax; y++) {
892          GLdepth *d = Z_ADDRESS( ctx, ctx->Buffer->Xmin, y );
893          GLint n = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1;
894          do {
895             *d++ = clear_value;
896             n--;
897          } while (n);
898       }
899    }
900    else {
901       /* clear whole buffer */
902       GLdepth *d = ctx->Buffer->Depth;
903       GLint n = ctx->Buffer->Width * ctx->Buffer->Height;
904       while (n>=16) {
905          d[0] = clear_value;    d[1] = clear_value;
906          d[2] = clear_value;    d[3] = clear_value;
907          d[4] = clear_value;    d[5] = clear_value;
908          d[6] = clear_value;    d[7] = clear_value;
909          d[8] = clear_value;    d[9] = clear_value;
910          d[10] = clear_value;   d[11] = clear_value;
911          d[12] = clear_value;   d[13] = clear_value;
912          d[14] = clear_value;   d[15] = clear_value;
913          d += 16;
914          n -= 16;
915       }
916       while (n>0) {
917          *d++ = clear_value;
918          n--;
919       }
920    }
921 }
922 
923 
924 
925