Replace the flags Mesa was using for ctx->NewState with a new set
[mesa.git] / src / mesa / main / depth.c
1 /* $Id: depth.c,v 1.21 2000/10/30 13:32:00 keithw Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28 #ifdef PC_HEADER
29 #include "all.h"
30 #else
31 #include "glheader.h"
32 #include "context.h"
33 #include "enums.h"
34 #include "depth.h"
35 #include "macros.h"
36 #include "mem.h"
37 #include "pb.h"
38 #include "types.h"
39 #endif
40
41
42
43 /**********************************************************************/
44 /***** API Functions *****/
45 /**********************************************************************/
46
47
48
49 void
50 _mesa_ClearDepth( GLclampd depth )
51 {
52 GET_CURRENT_CONTEXT(ctx);
53 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glClearDepth");
54 ctx->Depth.Clear = (GLfloat) CLAMP( depth, 0.0, 1.0 );
55 if (ctx->Driver.ClearDepth)
56 (*ctx->Driver.ClearDepth)( ctx, ctx->Depth.Clear );
57 ctx->NewState |= _NEW_DEPTH;
58 }
59
60
61
62 void
63 _mesa_DepthFunc( GLenum func )
64 {
65 GET_CURRENT_CONTEXT(ctx);
66 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDepthFunc");
67
68 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
69 fprintf(stderr, "glDepthFunc %s\n", gl_lookup_enum_by_nr(func));
70
71 switch (func) {
72 case GL_LESS: /* (default) pass if incoming z < stored z */
73 case GL_GEQUAL:
74 case GL_LEQUAL:
75 case GL_GREATER:
76 case GL_NOTEQUAL:
77 case GL_EQUAL:
78 case GL_ALWAYS:
79 if (ctx->Depth.Func != func) {
80 ctx->Depth.Func = func;
81 ctx->NewState |= _NEW_DEPTH;
82 ctx->TriangleCaps &= ~DD_Z_NEVER;
83 if (ctx->Driver.DepthFunc) {
84 (*ctx->Driver.DepthFunc)( ctx, func );
85 }
86 }
87 break;
88 case GL_NEVER:
89 if (ctx->Depth.Func != func) {
90 ctx->Depth.Func = func;
91 ctx->NewState |= _NEW_DEPTH;
92 ctx->TriangleCaps |= DD_Z_NEVER;
93 if (ctx->Driver.DepthFunc) {
94 (*ctx->Driver.DepthFunc)( ctx, func );
95 }
96 }
97 break;
98 default:
99 gl_error( ctx, GL_INVALID_ENUM, "glDepth.Func" );
100 }
101 }
102
103
104
105 void
106 _mesa_DepthMask( GLboolean flag )
107 {
108 GET_CURRENT_CONTEXT(ctx);
109 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDepthMask");
110
111 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
112 fprintf(stderr, "glDepthMask %d\n", flag);
113
114 /*
115 * GL_TRUE indicates depth buffer writing is enabled (default)
116 * GL_FALSE indicates depth buffer writing is disabled
117 */
118 if (ctx->Depth.Mask != flag) {
119 ctx->Depth.Mask = flag;
120 ctx->NewState |= _NEW_DEPTH;
121 if (ctx->Driver.DepthMask) {
122 (*ctx->Driver.DepthMask)( ctx, flag );
123 }
124 }
125 }
126
127
128
129 /**********************************************************************/
130 /***** Misc *****/
131 /**********************************************************************/
132
133 /*
134 * Return address of depth buffer value for given window coord.
135 */
136 GLvoid *
137 _mesa_zbuffer_address(GLcontext *ctx, GLint x, GLint y)
138 {
139 if (ctx->Visual.DepthBits <= 16)
140 return (GLushort *) ctx->DrawBuffer->DepthBuffer + ctx->DrawBuffer->Width * y + x;
141 else
142 return (GLuint *) ctx->DrawBuffer->DepthBuffer + ctx->DrawBuffer->Width * y + x;
143 }
144
145
146 #define Z_ADDRESS16( CTX, X, Y ) \
147 ( ((GLushort *) (CTX)->DrawBuffer->DepthBuffer) \
148 + (CTX)->DrawBuffer->Width * (Y) + (X) )
149
150 #define Z_ADDRESS32( CTX, X, Y ) \
151 ( ((GLuint *) (CTX)->DrawBuffer->DepthBuffer) \
152 + (CTX)->DrawBuffer->Width * (Y) + (X) )
153
154
155
156 /**********************************************************************/
157 /***** Depth Testing Functions *****/
158 /**********************************************************************/
159
160
161 /*
162 * Do depth test for an array of fragments. This is used both for
163 * software and hardware Z buffers.
164 * Input: zbuffer - array of z values in the zbuffer
165 * z - array of fragment z values
166 * Return: number of fragments which pass the test.
167 */
168 static GLuint
169 depth_test_span16( GLcontext *ctx, GLuint n, GLint x, GLint y,
170 GLushort zbuffer[], const GLdepth z[], GLubyte mask[] )
171 {
172 GLuint passed = 0;
173
174 /* switch cases ordered from most frequent to less frequent */
175 switch (ctx->Depth.Func) {
176 case GL_LESS:
177 if (ctx->Depth.Mask) {
178 /* Update Z buffer */
179 GLuint i;
180 for (i=0; i<n; i++) {
181 if (mask[i]) {
182 if (z[i] < zbuffer[i]) {
183 /* pass */
184 zbuffer[i] = z[i];
185 passed++;
186 }
187 else {
188 /* fail */
189 mask[i] = 0;
190 }
191 }
192 }
193 }
194 else {
195 /* Don't update Z buffer */
196 GLuint i;
197 for (i=0; i<n; i++) {
198 if (mask[i]) {
199 if (z[i] < zbuffer[i]) {
200 /* pass */
201 passed++;
202 }
203 else {
204 mask[i] = 0;
205 }
206 }
207 }
208 }
209 break;
210 case GL_LEQUAL:
211 if (ctx->Depth.Mask) {
212 /* Update Z buffer */
213 GLuint i;
214 for (i=0;i<n;i++) {
215 if (mask[i]) {
216 if (z[i] <= zbuffer[i]) {
217 zbuffer[i] = z[i];
218 passed++;
219 }
220 else {
221 mask[i] = 0;
222 }
223 }
224 }
225 }
226 else {
227 /* Don't update Z buffer */
228 GLuint i;
229 for (i=0;i<n;i++) {
230 if (mask[i]) {
231 if (z[i] <= zbuffer[i]) {
232 /* pass */
233 passed++;
234 }
235 else {
236 mask[i] = 0;
237 }
238 }
239 }
240 }
241 break;
242 case GL_GEQUAL:
243 if (ctx->Depth.Mask) {
244 /* Update Z buffer */
245 GLuint i;
246 for (i=0;i<n;i++) {
247 if (mask[i]) {
248 if (z[i] >= zbuffer[i]) {
249 zbuffer[i] = z[i];
250 passed++;
251 }
252 else {
253 mask[i] = 0;
254 }
255 }
256 }
257 }
258 else {
259 /* Don't update Z buffer */
260 GLuint i;
261 for (i=0;i<n;i++) {
262 if (mask[i]) {
263 if (z[i] >= zbuffer[i]) {
264 /* pass */
265 passed++;
266 }
267 else {
268 mask[i] = 0;
269 }
270 }
271 }
272 }
273 break;
274 case GL_GREATER:
275 if (ctx->Depth.Mask) {
276 /* Update Z buffer */
277 GLuint i;
278 for (i=0;i<n;i++) {
279 if (mask[i]) {
280 if (z[i] > zbuffer[i]) {
281 zbuffer[i] = z[i];
282 passed++;
283 }
284 else {
285 mask[i] = 0;
286 }
287 }
288 }
289 }
290 else {
291 /* Don't update Z buffer */
292 GLuint i;
293 for (i=0;i<n;i++) {
294 if (mask[i]) {
295 if (z[i] > zbuffer[i]) {
296 /* pass */
297 passed++;
298 }
299 else {
300 mask[i] = 0;
301 }
302 }
303 }
304 }
305 break;
306 case GL_NOTEQUAL:
307 if (ctx->Depth.Mask) {
308 /* Update Z buffer */
309 GLuint i;
310 for (i=0;i<n;i++) {
311 if (mask[i]) {
312 if (z[i] != zbuffer[i]) {
313 zbuffer[i] = z[i];
314 passed++;
315 }
316 else {
317 mask[i] = 0;
318 }
319 }
320 }
321 }
322 else {
323 /* Don't update Z buffer */
324 GLuint i;
325 for (i=0;i<n;i++) {
326 if (mask[i]) {
327 if (z[i] != zbuffer[i]) {
328 /* pass */
329 passed++;
330 }
331 else {
332 mask[i] = 0;
333 }
334 }
335 }
336 }
337 break;
338 case GL_EQUAL:
339 if (ctx->Depth.Mask) {
340 /* Update Z buffer */
341 GLuint i;
342 for (i=0;i<n;i++) {
343 if (mask[i]) {
344 if (z[i] == zbuffer[i]) {
345 zbuffer[i] = z[i];
346 passed++;
347 }
348 else {
349 mask[i] = 0;
350 }
351 }
352 }
353 }
354 else {
355 /* Don't update Z buffer */
356 GLuint i;
357 for (i=0;i<n;i++) {
358 if (mask[i]) {
359 if (z[i] == zbuffer[i]) {
360 /* pass */
361 passed++;
362 }
363 else {
364 mask[i] = 0;
365 }
366 }
367 }
368 }
369 break;
370 case GL_ALWAYS:
371 if (ctx->Depth.Mask) {
372 /* Update Z buffer */
373 GLuint i;
374 for (i=0;i<n;i++) {
375 if (mask[i]) {
376 zbuffer[i] = z[i];
377 passed++;
378 }
379 }
380 }
381 else {
382 /* Don't update Z buffer or mask */
383 passed = n;
384 }
385 break;
386 case GL_NEVER:
387 BZERO(mask, n * sizeof(GLubyte));
388 break;
389 default:
390 gl_problem(ctx, "Bad depth func in depth_test_span16");
391 }
392
393 return passed;
394 }
395
396
397 static GLuint
398 depth_test_span32( GLcontext *ctx, GLuint n, GLint x, GLint y,
399 GLuint zbuffer[], const GLdepth z[], GLubyte mask[] )
400 {
401 GLuint passed = 0;
402
403 /* switch cases ordered from most frequent to less frequent */
404 switch (ctx->Depth.Func) {
405 case GL_LESS:
406 if (ctx->Depth.Mask) {
407 /* Update Z buffer */
408 GLuint i;
409 for (i=0; i<n; i++) {
410 if (mask[i]) {
411 if (z[i] < zbuffer[i]) {
412 /* pass */
413 zbuffer[i] = z[i];
414 passed++;
415 }
416 else {
417 /* fail */
418 mask[i] = 0;
419 }
420 }
421 }
422 }
423 else {
424 /* Don't update Z buffer */
425 GLuint i;
426 for (i=0; i<n; i++) {
427 if (mask[i]) {
428 if (z[i] < zbuffer[i]) {
429 /* pass */
430 passed++;
431 }
432 else {
433 mask[i] = 0;
434 }
435 }
436 }
437 }
438 break;
439 case GL_LEQUAL:
440 if (ctx->Depth.Mask) {
441 /* Update Z buffer */
442 GLuint i;
443 for (i=0;i<n;i++) {
444 if (mask[i]) {
445 if (z[i] <= zbuffer[i]) {
446 zbuffer[i] = z[i];
447 passed++;
448 }
449 else {
450 mask[i] = 0;
451 }
452 }
453 }
454 }
455 else {
456 /* Don't update Z buffer */
457 GLuint i;
458 for (i=0;i<n;i++) {
459 if (mask[i]) {
460 if (z[i] <= zbuffer[i]) {
461 /* pass */
462 passed++;
463 }
464 else {
465 mask[i] = 0;
466 }
467 }
468 }
469 }
470 break;
471 case GL_GEQUAL:
472 if (ctx->Depth.Mask) {
473 /* Update Z buffer */
474 GLuint i;
475 for (i=0;i<n;i++) {
476 if (mask[i]) {
477 if (z[i] >= zbuffer[i]) {
478 zbuffer[i] = z[i];
479 passed++;
480 }
481 else {
482 mask[i] = 0;
483 }
484 }
485 }
486 }
487 else {
488 /* Don't update Z buffer */
489 GLuint i;
490 for (i=0;i<n;i++) {
491 if (mask[i]) {
492 if (z[i] >= zbuffer[i]) {
493 /* pass */
494 passed++;
495 }
496 else {
497 mask[i] = 0;
498 }
499 }
500 }
501 }
502 break;
503 case GL_GREATER:
504 if (ctx->Depth.Mask) {
505 /* Update Z buffer */
506 GLuint i;
507 for (i=0;i<n;i++) {
508 if (mask[i]) {
509 if (z[i] > zbuffer[i]) {
510 zbuffer[i] = z[i];
511 passed++;
512 }
513 else {
514 mask[i] = 0;
515 }
516 }
517 }
518 }
519 else {
520 /* Don't update Z buffer */
521 GLuint i;
522 for (i=0;i<n;i++) {
523 if (mask[i]) {
524 if (z[i] > zbuffer[i]) {
525 /* pass */
526 passed++;
527 }
528 else {
529 mask[i] = 0;
530 }
531 }
532 }
533 }
534 break;
535 case GL_NOTEQUAL:
536 if (ctx->Depth.Mask) {
537 /* Update Z buffer */
538 GLuint i;
539 for (i=0;i<n;i++) {
540 if (mask[i]) {
541 if (z[i] != zbuffer[i]) {
542 zbuffer[i] = z[i];
543 passed++;
544 }
545 else {
546 mask[i] = 0;
547 }
548 }
549 }
550 }
551 else {
552 /* Don't update Z buffer */
553 GLuint i;
554 for (i=0;i<n;i++) {
555 if (mask[i]) {
556 if (z[i] != zbuffer[i]) {
557 /* pass */
558 passed++;
559 }
560 else {
561 mask[i] = 0;
562 }
563 }
564 }
565 }
566 break;
567 case GL_EQUAL:
568 if (ctx->Depth.Mask) {
569 /* Update Z buffer */
570 GLuint i;
571 for (i=0;i<n;i++) {
572 if (mask[i]) {
573 if (z[i] == zbuffer[i]) {
574 zbuffer[i] = z[i];
575 passed++;
576 }
577 else {
578 mask[i] = 0;
579 }
580 }
581 }
582 }
583 else {
584 /* Don't update Z buffer */
585 GLuint i;
586 for (i=0;i<n;i++) {
587 if (mask[i]) {
588 if (z[i] == zbuffer[i]) {
589 /* pass */
590 passed++;
591 }
592 else {
593 mask[i] = 0;
594 }
595 }
596 }
597 }
598 break;
599 case GL_ALWAYS:
600 if (ctx->Depth.Mask) {
601 /* Update Z buffer */
602 GLuint i;
603 for (i=0;i<n;i++) {
604 if (mask[i]) {
605 zbuffer[i] = z[i];
606 passed++;
607 }
608 }
609 }
610 else {
611 /* Don't update Z buffer or mask */
612 passed = n;
613 }
614 break;
615 case GL_NEVER:
616 BZERO(mask, n * sizeof(GLubyte));
617 break;
618 default:
619 gl_problem(ctx, "Bad depth func in depth_test_span32");
620 }
621
622 return passed;
623 }
624
625
626
627 /*
628 * Apply depth test to span of fragments. Hardware or software z buffer.
629 */
630 GLuint
631 _mesa_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
632 const GLdepth z[], GLubyte mask[] )
633 {
634 if (ctx->Driver.ReadDepthSpan) {
635 /* hardware-based depth buffer */
636 GLdepth zbuffer[MAX_WIDTH];
637 GLuint passed;
638 (*ctx->Driver.ReadDepthSpan)(ctx, n, x, y, zbuffer);
639 passed = depth_test_span32(ctx, n, x, y, zbuffer, z, mask);
640 assert(ctx->Driver.WriteDepthSpan);
641 (*ctx->Driver.WriteDepthSpan)(ctx, n, x, y, zbuffer, mask);
642 return passed;
643 }
644 else {
645 /* software depth buffer */
646 if (ctx->Visual.DepthBits <= 16) {
647 GLushort *zptr = (GLushort *) Z_ADDRESS16(ctx, x, y);
648 GLuint passed = depth_test_span16(ctx, n, x, y, zptr, z, mask);
649 return passed;
650 }
651 else {
652 GLuint *zptr = (GLuint *) Z_ADDRESS32(ctx, x, y);
653 GLuint passed = depth_test_span32(ctx, n, x, y, zptr, z, mask);
654 return passed;
655 }
656 }
657 }
658
659
660
661
662 /*
663 * Do depth testing for an array of fragments using software Z buffer.
664 */
665 static void
666 software_depth_test_pixels16( GLcontext *ctx, GLuint n,
667 const GLint x[], const GLint y[],
668 const GLdepth z[], GLubyte mask[] )
669 {
670 /* switch cases ordered from most frequent to less frequent */
671 switch (ctx->Depth.Func) {
672 case GL_LESS:
673 if (ctx->Depth.Mask) {
674 /* Update Z buffer */
675 GLuint i;
676 for (i=0; i<n; i++) {
677 if (mask[i]) {
678 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
679 if (z[i] < *zptr) {
680 /* pass */
681 *zptr = z[i];
682 }
683 else {
684 /* fail */
685 mask[i] = 0;
686 }
687 }
688 }
689 }
690 else {
691 /* Don't update Z buffer */
692 GLuint i;
693 for (i=0; i<n; i++) {
694 if (mask[i]) {
695 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
696 if (z[i] < *zptr) {
697 /* pass */
698 }
699 else {
700 /* fail */
701 mask[i] = 0;
702 }
703 }
704 }
705 }
706 break;
707 case GL_LEQUAL:
708 if (ctx->Depth.Mask) {
709 /* Update Z buffer */
710 GLuint i;
711 for (i=0; i<n; i++) {
712 if (mask[i]) {
713 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
714 if (z[i] <= *zptr) {
715 /* pass */
716 *zptr = z[i];
717 }
718 else {
719 /* fail */
720 mask[i] = 0;
721 }
722 }
723 }
724 }
725 else {
726 /* Don't update Z buffer */
727 GLuint i;
728 for (i=0; i<n; i++) {
729 if (mask[i]) {
730 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
731 if (z[i] <= *zptr) {
732 /* pass */
733 }
734 else {
735 /* fail */
736 mask[i] = 0;
737 }
738 }
739 }
740 }
741 break;
742 case GL_GEQUAL:
743 if (ctx->Depth.Mask) {
744 /* Update Z buffer */
745 GLuint i;
746 for (i=0; i<n; i++) {
747 if (mask[i]) {
748 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
749 if (z[i] >= *zptr) {
750 /* pass */
751 *zptr = z[i];
752 }
753 else {
754 /* fail */
755 mask[i] = 0;
756 }
757 }
758 }
759 }
760 else {
761 /* Don't update Z buffer */
762 GLuint i;
763 for (i=0; i<n; i++) {
764 if (mask[i]) {
765 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
766 if (z[i] >= *zptr) {
767 /* pass */
768 }
769 else {
770 /* fail */
771 mask[i] = 0;
772 }
773 }
774 }
775 }
776 break;
777 case GL_GREATER:
778 if (ctx->Depth.Mask) {
779 /* Update Z buffer */
780 GLuint i;
781 for (i=0; i<n; i++) {
782 if (mask[i]) {
783 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
784 if (z[i] > *zptr) {
785 /* pass */
786 *zptr = z[i];
787 }
788 else {
789 /* fail */
790 mask[i] = 0;
791 }
792 }
793 }
794 }
795 else {
796 /* Don't update Z buffer */
797 GLuint i;
798 for (i=0; i<n; i++) {
799 if (mask[i]) {
800 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
801 if (z[i] > *zptr) {
802 /* pass */
803 }
804 else {
805 /* fail */
806 mask[i] = 0;
807 }
808 }
809 }
810 }
811 break;
812 case GL_NOTEQUAL:
813 if (ctx->Depth.Mask) {
814 /* Update Z buffer */
815 GLuint i;
816 for (i=0; i<n; i++) {
817 if (mask[i]) {
818 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
819 if (z[i] != *zptr) {
820 /* pass */
821 *zptr = z[i];
822 }
823 else {
824 /* fail */
825 mask[i] = 0;
826 }
827 }
828 }
829 }
830 else {
831 /* Don't update Z buffer */
832 GLuint i;
833 for (i=0; i<n; i++) {
834 if (mask[i]) {
835 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
836 if (z[i] != *zptr) {
837 /* pass */
838 }
839 else {
840 /* fail */
841 mask[i] = 0;
842 }
843 }
844 }
845 }
846 break;
847 case GL_EQUAL:
848 if (ctx->Depth.Mask) {
849 /* Update Z buffer */
850 GLuint i;
851 for (i=0; i<n; i++) {
852 if (mask[i]) {
853 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
854 if (z[i] == *zptr) {
855 /* pass */
856 *zptr = z[i];
857 }
858 else {
859 /* fail */
860 mask[i] = 0;
861 }
862 }
863 }
864 }
865 else {
866 /* Don't update Z buffer */
867 GLuint i;
868 for (i=0; i<n; i++) {
869 if (mask[i]) {
870 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
871 if (z[i] == *zptr) {
872 /* pass */
873 }
874 else {
875 /* fail */
876 mask[i] = 0;
877 }
878 }
879 }
880 }
881 break;
882 case GL_ALWAYS:
883 if (ctx->Depth.Mask) {
884 /* Update Z buffer */
885 GLuint i;
886 for (i=0; i<n; i++) {
887 if (mask[i]) {
888 GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
889 *zptr = z[i];
890 }
891 }
892 }
893 else {
894 /* Don't update Z buffer or mask */
895 }
896 break;
897 case GL_NEVER:
898 /* depth test never passes */
899 BZERO(mask, n * sizeof(GLubyte));
900 break;
901 default:
902 gl_problem(ctx, "Bad depth func in software_depth_test_pixels");
903 }
904 }
905
906
907
908 /*
909 * Do depth testing for an array of fragments using software Z buffer.
910 */
911 static void
912 software_depth_test_pixels32( GLcontext *ctx, GLuint n,
913 const GLint x[], const GLint y[],
914 const GLdepth z[], GLubyte mask[] )
915 {
916 /* switch cases ordered from most frequent to less frequent */
917 switch (ctx->Depth.Func) {
918 case GL_LESS:
919 if (ctx->Depth.Mask) {
920 /* Update Z buffer */
921 GLuint i;
922 for (i=0; i<n; i++) {
923 if (mask[i]) {
924 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
925 if (z[i] < *zptr) {
926 /* pass */
927 *zptr = z[i];
928 }
929 else {
930 /* fail */
931 mask[i] = 0;
932 }
933 }
934 }
935 }
936 else {
937 /* Don't update Z buffer */
938 GLuint i;
939 for (i=0; i<n; i++) {
940 if (mask[i]) {
941 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
942 if (z[i] < *zptr) {
943 /* pass */
944 }
945 else {
946 /* fail */
947 mask[i] = 0;
948 }
949 }
950 }
951 }
952 break;
953 case GL_LEQUAL:
954 if (ctx->Depth.Mask) {
955 /* Update Z buffer */
956 GLuint i;
957 for (i=0; i<n; i++) {
958 if (mask[i]) {
959 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
960 if (z[i] <= *zptr) {
961 /* pass */
962 *zptr = z[i];
963 }
964 else {
965 /* fail */
966 mask[i] = 0;
967 }
968 }
969 }
970 }
971 else {
972 /* Don't update Z buffer */
973 GLuint i;
974 for (i=0; i<n; i++) {
975 if (mask[i]) {
976 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
977 if (z[i] <= *zptr) {
978 /* pass */
979 }
980 else {
981 /* fail */
982 mask[i] = 0;
983 }
984 }
985 }
986 }
987 break;
988 case GL_GEQUAL:
989 if (ctx->Depth.Mask) {
990 /* Update Z buffer */
991 GLuint i;
992 for (i=0; i<n; i++) {
993 if (mask[i]) {
994 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
995 if (z[i] >= *zptr) {
996 /* pass */
997 *zptr = z[i];
998 }
999 else {
1000 /* fail */
1001 mask[i] = 0;
1002 }
1003 }
1004 }
1005 }
1006 else {
1007 /* Don't update Z buffer */
1008 GLuint i;
1009 for (i=0; i<n; i++) {
1010 if (mask[i]) {
1011 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1012 if (z[i] >= *zptr) {
1013 /* pass */
1014 }
1015 else {
1016 /* fail */
1017 mask[i] = 0;
1018 }
1019 }
1020 }
1021 }
1022 break;
1023 case GL_GREATER:
1024 if (ctx->Depth.Mask) {
1025 /* Update Z buffer */
1026 GLuint i;
1027 for (i=0; i<n; i++) {
1028 if (mask[i]) {
1029 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1030 if (z[i] > *zptr) {
1031 /* pass */
1032 *zptr = z[i];
1033 }
1034 else {
1035 /* fail */
1036 mask[i] = 0;
1037 }
1038 }
1039 }
1040 }
1041 else {
1042 /* Don't update Z buffer */
1043 GLuint i;
1044 for (i=0; i<n; i++) {
1045 if (mask[i]) {
1046 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1047 if (z[i] > *zptr) {
1048 /* pass */
1049 }
1050 else {
1051 /* fail */
1052 mask[i] = 0;
1053 }
1054 }
1055 }
1056 }
1057 break;
1058 case GL_NOTEQUAL:
1059 if (ctx->Depth.Mask) {
1060 /* Update Z buffer */
1061 GLuint i;
1062 for (i=0; i<n; i++) {
1063 if (mask[i]) {
1064 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1065 if (z[i] != *zptr) {
1066 /* pass */
1067 *zptr = z[i];
1068 }
1069 else {
1070 /* fail */
1071 mask[i] = 0;
1072 }
1073 }
1074 }
1075 }
1076 else {
1077 /* Don't update Z buffer */
1078 GLuint i;
1079 for (i=0; i<n; i++) {
1080 if (mask[i]) {
1081 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1082 if (z[i] != *zptr) {
1083 /* pass */
1084 }
1085 else {
1086 /* fail */
1087 mask[i] = 0;
1088 }
1089 }
1090 }
1091 }
1092 break;
1093 case GL_EQUAL:
1094 if (ctx->Depth.Mask) {
1095 /* Update Z buffer */
1096 GLuint i;
1097 for (i=0; i<n; i++) {
1098 if (mask[i]) {
1099 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1100 if (z[i] == *zptr) {
1101 /* pass */
1102 *zptr = z[i];
1103 }
1104 else {
1105 /* fail */
1106 mask[i] = 0;
1107 }
1108 }
1109 }
1110 }
1111 else {
1112 /* Don't update Z buffer */
1113 GLuint i;
1114 for (i=0; i<n; i++) {
1115 if (mask[i]) {
1116 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1117 if (z[i] == *zptr) {
1118 /* pass */
1119 }
1120 else {
1121 /* fail */
1122 mask[i] = 0;
1123 }
1124 }
1125 }
1126 }
1127 break;
1128 case GL_ALWAYS:
1129 if (ctx->Depth.Mask) {
1130 /* Update Z buffer */
1131 GLuint i;
1132 for (i=0; i<n; i++) {
1133 if (mask[i]) {
1134 GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
1135 *zptr = z[i];
1136 }
1137 }
1138 }
1139 else {
1140 /* Don't update Z buffer or mask */
1141 }
1142 break;
1143 case GL_NEVER:
1144 /* depth test never passes */
1145 BZERO(mask, n * sizeof(GLubyte));
1146 break;
1147 default:
1148 gl_problem(ctx, "Bad depth func in software_depth_test_pixels");
1149 }
1150 }
1151
1152
1153
1154 /*
1155 * Do depth testing for an array of pixels using hardware Z buffer.
1156 * Input/output: zbuffer - array of depth values from Z buffer
1157 * Input: z - array of fragment z values.
1158 */
1159 static void
1160 hardware_depth_test_pixels( GLcontext *ctx, GLuint n, GLdepth zbuffer[],
1161 const GLdepth z[], GLubyte mask[] )
1162 {
1163 /* switch cases ordered from most frequent to less frequent */
1164 switch (ctx->Depth.Func) {
1165 case GL_LESS:
1166 if (ctx->Depth.Mask) {
1167 /* Update Z buffer */
1168 GLuint i;
1169 for (i=0; i<n; i++) {
1170 if (mask[i]) {
1171 if (z[i] < zbuffer[i]) {
1172 /* pass */
1173 zbuffer[i] = z[i];
1174 }
1175 else {
1176 /* fail */
1177 mask[i] = 0;
1178 }
1179 }
1180 }
1181 }
1182 else {
1183 /* Don't update Z buffer */
1184 GLuint i;
1185 for (i=0; i<n; i++) {
1186 if (mask[i]) {
1187 if (z[i] < zbuffer[i]) {
1188 /* pass */
1189 }
1190 else {
1191 /* fail */
1192 mask[i] = 0;
1193 }
1194 }
1195 }
1196 }
1197 break;
1198 case GL_LEQUAL:
1199 if (ctx->Depth.Mask) {
1200 /* Update Z buffer */
1201 GLuint i;
1202 for (i=0; i<n; i++) {
1203 if (mask[i]) {
1204 if (z[i] <= zbuffer[i]) {
1205 /* pass */
1206 zbuffer[i] = z[i];
1207 }
1208 else {
1209 /* fail */
1210 mask[i] = 0;
1211 }
1212 }
1213 }
1214 }
1215 else {
1216 /* Don't update Z buffer */
1217 GLuint i;
1218 for (i=0; i<n; i++) {
1219 if (mask[i]) {
1220 if (z[i] <= zbuffer[i]) {
1221 /* pass */
1222 }
1223 else {
1224 /* fail */
1225 mask[i] = 0;
1226 }
1227 }
1228 }
1229 }
1230 break;
1231 case GL_GEQUAL:
1232 if (ctx->Depth.Mask) {
1233 /* Update Z buffer */
1234 GLuint i;
1235 for (i=0; i<n; i++) {
1236 if (mask[i]) {
1237 if (z[i] >= zbuffer[i]) {
1238 /* pass */
1239 zbuffer[i] = z[i];
1240 }
1241 else {
1242 /* fail */
1243 mask[i] = 0;
1244 }
1245 }
1246 }
1247 }
1248 else {
1249 /* Don't update Z buffer */
1250 GLuint i;
1251 for (i=0; i<n; i++) {
1252 if (mask[i]) {
1253 if (z[i] >= zbuffer[i]) {
1254 /* pass */
1255 }
1256 else {
1257 /* fail */
1258 mask[i] = 0;
1259 }
1260 }
1261 }
1262 }
1263 break;
1264 case GL_GREATER:
1265 if (ctx->Depth.Mask) {
1266 /* Update Z buffer */
1267 GLuint i;
1268 for (i=0; i<n; i++) {
1269 if (mask[i]) {
1270 if (z[i] > zbuffer[i]) {
1271 /* pass */
1272 zbuffer[i] = z[i];
1273 }
1274 else {
1275 /* fail */
1276 mask[i] = 0;
1277 }
1278 }
1279 }
1280 }
1281 else {
1282 /* Don't update Z buffer */
1283 GLuint i;
1284 for (i=0; i<n; i++) {
1285 if (mask[i]) {
1286 if (z[i] > zbuffer[i]) {
1287 /* pass */
1288 }
1289 else {
1290 /* fail */
1291 mask[i] = 0;
1292 }
1293 }
1294 }
1295 }
1296 break;
1297 case GL_NOTEQUAL:
1298 if (ctx->Depth.Mask) {
1299 /* Update Z buffer */
1300 GLuint i;
1301 for (i=0; i<n; i++) {
1302 if (mask[i]) {
1303 if (z[i] != zbuffer[i]) {
1304 /* pass */
1305 zbuffer[i] = z[i];
1306 }
1307 else {
1308 /* fail */
1309 mask[i] = 0;
1310 }
1311 }
1312 }
1313 }
1314 else {
1315 /* Don't update Z buffer */
1316 GLuint i;
1317 for (i=0; i<n; i++) {
1318 if (mask[i]) {
1319 if (z[i] != zbuffer[i]) {
1320 /* pass */
1321 }
1322 else {
1323 /* fail */
1324 mask[i] = 0;
1325 }
1326 }
1327 }
1328 }
1329 break;
1330 case GL_EQUAL:
1331 if (ctx->Depth.Mask) {
1332 /* Update Z buffer */
1333 GLuint i;
1334 for (i=0; i<n; i++) {
1335 if (mask[i]) {
1336 if (z[i] == zbuffer[i]) {
1337 /* pass */
1338 zbuffer[i] = z[i];
1339 }
1340 else {
1341 /* fail */
1342 mask[i] = 0;
1343 }
1344 }
1345 }
1346 }
1347 else {
1348 /* Don't update Z buffer */
1349 GLuint i;
1350 for (i=0; i<n; i++) {
1351 if (mask[i]) {
1352 if (z[i] == zbuffer[i]) {
1353 /* pass */
1354 }
1355 else {
1356 /* fail */
1357 mask[i] = 0;
1358 }
1359 }
1360 }
1361 }
1362 break;
1363 case GL_ALWAYS:
1364 if (ctx->Depth.Mask) {
1365 /* Update Z buffer */
1366 GLuint i;
1367 for (i=0; i<n; i++) {
1368 if (mask[i]) {
1369 zbuffer[i] = z[i];
1370 }
1371 }
1372 }
1373 else {
1374 /* Don't update Z buffer or mask */
1375 }
1376 break;
1377 case GL_NEVER:
1378 /* depth test never passes */
1379 BZERO(mask, n * sizeof(GLubyte));
1380 break;
1381 default:
1382 gl_problem(ctx, "Bad depth func in hardware_depth_test_pixels");
1383 }
1384 }
1385
1386
1387
1388 void
1389 _mesa_depth_test_pixels( GLcontext *ctx,
1390 GLuint n, const GLint x[], const GLint y[],
1391 const GLdepth z[], GLubyte mask[] )
1392 {
1393 if (ctx->Driver.ReadDepthPixels) {
1394 /* read depth values from hardware Z buffer */
1395 GLdepth zbuffer[PB_SIZE];
1396 (*ctx->Driver.ReadDepthPixels)(ctx, n, x, y, zbuffer);
1397
1398 hardware_depth_test_pixels( ctx, n, zbuffer, z, mask );
1399
1400 /* update hardware Z buffer with new values */
1401 assert(ctx->Driver.WriteDepthPixels);
1402 (*ctx->Driver.WriteDepthPixels)(ctx, n, x, y, zbuffer, mask );
1403 }
1404 else {
1405 /* software depth testing */
1406 if (ctx->Visual.DepthBits <= 16)
1407 software_depth_test_pixels16(ctx, n, x, y, z, mask);
1408 else
1409 software_depth_test_pixels32(ctx, n, x, y, z, mask);
1410 }
1411 }
1412
1413
1414
1415
1416
1417 /**********************************************************************/
1418 /***** Read Depth Buffer *****/
1419 /**********************************************************************/
1420
1421
1422 /*
1423 * Read a span of depth values from the depth buffer.
1424 * This function does clipping before calling the device driver function.
1425 */
1426 void
1427 _mesa_read_depth_span( GLcontext *ctx,
1428 GLint n, GLint x, GLint y, GLdepth depth[] )
1429 {
1430 if (y < 0 || y >= ctx->DrawBuffer->Height ||
1431 x + (GLint) n <= 0 || x >= ctx->DrawBuffer->Width) {
1432 /* span is completely outside framebuffer */
1433 GLint i;
1434 for (i = 0; i < n; i++)
1435 depth[i] = 0;
1436 return;
1437 }
1438
1439 if (x < 0) {
1440 GLint dx = -x;
1441 GLint i;
1442 for (i = 0; i < dx; i++)
1443 depth[i] = 0;
1444 x = 0;
1445 n -= dx;
1446 depth += dx;
1447 }
1448 if (x + n > ctx->DrawBuffer->Width) {
1449 GLint dx = x + n - ctx->DrawBuffer->Width;
1450 GLint i;
1451 for (i = 0; i < dx; i++)
1452 depth[n - i - 1] = 0;
1453 n -= dx;
1454 }
1455 if (n <= 0) {
1456 return;
1457 }
1458
1459 if (ctx->DrawBuffer->DepthBuffer) {
1460 /* read from software depth buffer */
1461 if (ctx->Visual.DepthBits <= 16) {
1462 const GLushort *zptr = Z_ADDRESS16( ctx, x, y );
1463 GLuint i;
1464 for (i = 0; i < n; i++) {
1465 depth[i] = zptr[i];
1466 }
1467 }
1468 else {
1469 const GLuint *zptr = Z_ADDRESS32( ctx, x, y );
1470 GLuint i;
1471 for (i = 0; i < n; i++) {
1472 depth[i] = zptr[i];
1473 }
1474 }
1475 }
1476 else if (ctx->Driver.ReadDepthSpan) {
1477 /* read from hardware depth buffer */
1478 (*ctx->Driver.ReadDepthSpan)( ctx, n, x, y, depth );
1479 }
1480 else {
1481 /* no depth buffer */
1482 BZERO(depth, n * sizeof(GLfloat));
1483 }
1484
1485 }
1486
1487
1488
1489
1490 /*
1491 * Return a span of depth values from the depth buffer as floats in [0,1].
1492 * This is used for both hardware and software depth buffers.
1493 * Input: n - how many pixels
1494 * x,y - location of first pixel
1495 * Output: depth - the array of depth values
1496 */
1497 void
1498 _mesa_read_depth_span_float( GLcontext *ctx,
1499 GLint n, GLint x, GLint y, GLfloat depth[] )
1500 {
1501 const GLfloat scale = 1.0F / ctx->Visual.DepthMaxF;
1502
1503 if (y < 0 || y >= ctx->DrawBuffer->Height ||
1504 x + (GLint) n <= 0 || x >= ctx->DrawBuffer->Width) {
1505 /* span is completely outside framebuffer */
1506 GLint i;
1507 for (i = 0; i < n; i++)
1508 depth[i] = 0.0F;
1509 return;
1510 }
1511
1512 if (x < 0) {
1513 GLint dx = -x;
1514 GLint i;
1515 for (i = 0; i < dx; i++)
1516 depth[i] = 0.0F;
1517 n -= dx;
1518 x = 0;
1519 }
1520 if (x + n > ctx->DrawBuffer->Width) {
1521 GLint dx = x + n - ctx->DrawBuffer->Width;
1522 GLint i;
1523 for (i = 0; i < dx; i++)
1524 depth[n - i - 1] = 0.0F;
1525 n -= dx;
1526 }
1527 if (n <= 0) {
1528 return;
1529 }
1530
1531 if (ctx->DrawBuffer->DepthBuffer) {
1532 /* read from software depth buffer */
1533 if (ctx->Visual.DepthBits <= 16) {
1534 const GLushort *zptr = Z_ADDRESS16( ctx, x, y );
1535 GLuint i;
1536 for (i = 0; i < n; i++) {
1537 depth[i] = (GLfloat) zptr[i] * scale;
1538 }
1539 }
1540 else {
1541 const GLuint *zptr = Z_ADDRESS32( ctx, x, y );
1542 GLuint i;
1543 for (i = 0; i < n; i++) {
1544 depth[i] = (GLfloat) zptr[i] * scale;
1545 }
1546 }
1547 }
1548 else if (ctx->Driver.ReadDepthSpan) {
1549 /* read from hardware depth buffer */
1550 GLdepth d[MAX_WIDTH];
1551 GLuint i;
1552 assert(n <= MAX_WIDTH);
1553 (*ctx->Driver.ReadDepthSpan)( ctx, n, x, y, d );
1554 for (i = 0; i < n; i++) {
1555 depth[i] = d[i] * scale;
1556 }
1557 }
1558 else {
1559 /* no depth buffer */
1560 BZERO(depth, n * sizeof(GLfloat));
1561 }
1562 }
1563
1564
1565
1566 /**********************************************************************/
1567 /***** Allocate and Clear Depth Buffer *****/
1568 /**********************************************************************/
1569
1570
1571
1572 /*
1573 * Allocate a new depth buffer. If there's already a depth buffer allocated
1574 * it will be free()'d. The new depth buffer will be uniniitalized.
1575 * This function is only called through Driver.alloc_depth_buffer.
1576 */
1577 void
1578 _mesa_alloc_depth_buffer( GLcontext *ctx )
1579 {
1580 /* deallocate current depth buffer if present */
1581 if (ctx->DrawBuffer->UseSoftwareDepthBuffer) {
1582 GLint bytesPerValue;
1583
1584 if (ctx->DrawBuffer->DepthBuffer) {
1585 FREE(ctx->DrawBuffer->DepthBuffer);
1586 ctx->DrawBuffer->DepthBuffer = NULL;
1587 }
1588
1589 /* allocate new depth buffer, but don't initialize it */
1590 if (ctx->Visual.DepthBits <= 16)
1591 bytesPerValue = sizeof(GLushort);
1592 else
1593 bytesPerValue = sizeof(GLuint);
1594
1595 ctx->DrawBuffer->DepthBuffer = MALLOC( ctx->DrawBuffer->Width
1596 * ctx->DrawBuffer->Height
1597 * bytesPerValue );
1598
1599 if (!ctx->DrawBuffer->DepthBuffer) {
1600 /* out of memory */
1601 ctx->Depth.Test = GL_FALSE;
1602 ctx->NewState |= _NEW_DEPTH;
1603 gl_error( ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer" );
1604 }
1605 }
1606 }
1607
1608
1609
1610
1611 /*
1612 * Clear the depth buffer. If the depth buffer doesn't exist yet we'll
1613 * allocate it now.
1614 * This function is only called through Driver.clear_depth_buffer.
1615 */
1616 void
1617 _mesa_clear_depth_buffer( GLcontext *ctx )
1618 {
1619 if (ctx->Visual.DepthBits == 0
1620 || !ctx->DrawBuffer->DepthBuffer
1621 || !ctx->Depth.Mask) {
1622 /* no depth buffer, or writing to it is disabled */
1623 return;
1624 }
1625
1626 /* The loops in this function have been written so the IRIX 5.3
1627 * C compiler can unroll them. Hopefully other compilers can too!
1628 */
1629
1630 if (ctx->Scissor.Enabled) {
1631 /* only clear scissor region */
1632 if (ctx->Visual.DepthBits <= 16) {
1633 const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->Visual.DepthMax);
1634 const GLint rows = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin;
1635 const GLint width = ctx->DrawBuffer->Width;
1636 GLushort *dRow = (GLushort *) ctx->DrawBuffer->DepthBuffer
1637 + ctx->DrawBuffer->Ymin * width + ctx->DrawBuffer->Xmin;
1638 GLint i, j;
1639 for (i = 0; i < rows; i++) {
1640 for (j = 0; j < width; j++) {
1641 dRow[j] = clearValue;
1642 }
1643 dRow += width;
1644 }
1645 }
1646 else {
1647 const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->Visual.DepthMax);
1648 const GLint rows = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin;
1649 const GLint width = ctx->DrawBuffer->Width;
1650 GLuint *dRow = (GLuint *) ctx->DrawBuffer->DepthBuffer
1651 + ctx->DrawBuffer->Ymin * width + ctx->DrawBuffer->Xmin;
1652 GLint i, j;
1653 for (i = 0; i < rows; i++) {
1654 for (j = 0; j < width; j++) {
1655 dRow[j] = clearValue;
1656 }
1657 dRow += width;
1658 }
1659 }
1660 }
1661 else {
1662 /* clear whole buffer */
1663 if (ctx->Visual.DepthBits <= 16) {
1664 const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->Visual.DepthMax);
1665 if ((clearValue & 0xff) == (clearValue >> 8)) {
1666 if (clearValue == 0) {
1667 BZERO(ctx->DrawBuffer->DepthBuffer,
1668 2*ctx->DrawBuffer->Width*ctx->DrawBuffer->Height);
1669 }
1670 else {
1671 /* lower and upper bytes of clear_value are same, use MEMSET */
1672 MEMSET( ctx->DrawBuffer->DepthBuffer, clearValue & 0xff,
1673 2 * ctx->DrawBuffer->Width * ctx->DrawBuffer->Height);
1674 }
1675 }
1676 else {
1677 GLushort *d = (GLushort *) ctx->DrawBuffer->DepthBuffer;
1678 GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
1679 while (n >= 16) {
1680 d[0] = clearValue; d[1] = clearValue;
1681 d[2] = clearValue; d[3] = clearValue;
1682 d[4] = clearValue; d[5] = clearValue;
1683 d[6] = clearValue; d[7] = clearValue;
1684 d[8] = clearValue; d[9] = clearValue;
1685 d[10] = clearValue; d[11] = clearValue;
1686 d[12] = clearValue; d[13] = clearValue;
1687 d[14] = clearValue; d[15] = clearValue;
1688 d += 16;
1689 n -= 16;
1690 }
1691 while (n > 0) {
1692 *d++ = clearValue;
1693 n--;
1694 }
1695 }
1696 }
1697 else {
1698 /* >16 bit depth buffer */
1699 const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->Visual.DepthMax);
1700 if (clearValue == 0) {
1701 BZERO(ctx->DrawBuffer->DepthBuffer,
1702 ctx->DrawBuffer->Width*ctx->DrawBuffer->Height*sizeof(GLuint));
1703 }
1704 else {
1705 GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
1706 GLuint *d = (GLuint *) ctx->DrawBuffer->DepthBuffer;
1707 while (n >= 16) {
1708 d[0] = clearValue; d[1] = clearValue;
1709 d[2] = clearValue; d[3] = clearValue;
1710 d[4] = clearValue; d[5] = clearValue;
1711 d[6] = clearValue; d[7] = clearValue;
1712 d[8] = clearValue; d[9] = clearValue;
1713 d[10] = clearValue; d[11] = clearValue;
1714 d[12] = clearValue; d[13] = clearValue;
1715 d[14] = clearValue; d[15] = clearValue;
1716 d += 16;
1717 n -= 16;
1718 }
1719 while (n > 0) {
1720 *d++ = clearValue;
1721 n--;
1722 }
1723 }
1724 }
1725 }
1726 }