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